Exemple #1
0
        protected ActionResult <TContentType?> PerformPostSave <TContentTypeDisplay, TContentTypeSave, TPropertyType>(
            TContentTypeSave contentTypeSave,
            Func <int, TContentType?> getContentType,
            Action <TContentType?> saveContentType,
            Action <TContentTypeSave>?beforeCreateNew = null)
            where TContentTypeDisplay : ContentTypeCompositionDisplay
            where TContentTypeSave : ContentTypeSave <TPropertyType>
            where TPropertyType : PropertyTypeBasic
        {
            var          ctId = Convert.ToInt32(contentTypeSave.Id);
            TContentType?ct   = ctId > 0 ? getContentType(ctId) : null;

            if (ctId > 0 && ct == null)
            {
                return(NotFound());
            }

            //Validate that there's no other ct with the same alias
            // it in fact cannot be the same as any content type alias (member, content or media) because
            // this would interfere with how ModelsBuilder works and also how many of the published caches
            // works since that is based on aliases.
            IEnumerable <string> allAliases = ContentTypeService.GetAllContentTypeAliases();
            var exists = allAliases.InvariantContains(contentTypeSave.Alias);

            if (exists && (ctId == 0 || (!ct?.Alias.InvariantEquals(contentTypeSave.Alias) ?? false)))
            {
                ModelState.AddModelError("Alias",
                                         LocalizedTextService.Localize("editcontenttype", "aliasAlreadyExists"));
            }

            // execute the external validators
            ValidateExternalValidators(ModelState, contentTypeSave);

            if (ModelState.IsValid == false)
            {
                TContentTypeDisplay?err =
                    CreateModelStateValidationEror <TContentTypeSave, TContentTypeDisplay>(ctId, contentTypeSave, ct);
                return(ValidationProblem(err));
            }

            //filter out empty properties
            contentTypeSave.Groups = contentTypeSave.Groups.Where(x => x.Name.IsNullOrWhiteSpace() == false).ToList();
            foreach (PropertyGroupBasic <TPropertyType> group in contentTypeSave.Groups)
            {
                group.Properties = group.Properties.Where(x => x.Alias.IsNullOrWhiteSpace() == false).ToList();
            }

            if (ctId > 0)
            {
                //its an update to an existing content type

                //This mapping will cause a lot of content type validation to occur which we need to deal with
                try
                {
                    UmbracoMapper.Map(contentTypeSave, ct);
                }
                catch (Exception ex)
                {
                    TContentTypeDisplay?responseEx =
                        CreateInvalidCompositionResponseException <TContentTypeDisplay, TContentTypeSave, TPropertyType>(
                            ex, contentTypeSave, ct, ctId);
                    if (responseEx != null)
                    {
                        return(ValidationProblem(responseEx));
                    }
                }

                TContentTypeDisplay?exResult =
                    CreateCompositionValidationExceptionIfInvalid <TContentTypeSave, TPropertyType, TContentTypeDisplay>(
                        contentTypeSave, ct);
                if (exResult != null)
                {
                    return(ValidationProblem(exResult));
                }

                saveContentType(ct);

                return(ct);
            }
            else
            {
                if (beforeCreateNew != null)
                {
                    beforeCreateNew(contentTypeSave);
                }

                //check if the type is trying to allow type 0 below itself - id zero refers to the currently unsaved type
                //always filter these 0 types out
                var allowItselfAsChild          = false;
                var allowIfselfAsChildSortOrder = -1;
                if (contentTypeSave.AllowedContentTypes != null)
                {
                    allowIfselfAsChildSortOrder = contentTypeSave.AllowedContentTypes.IndexOf(0);
                    allowItselfAsChild          = contentTypeSave.AllowedContentTypes.Any(x => x == 0);

                    contentTypeSave.AllowedContentTypes =
                        contentTypeSave.AllowedContentTypes.Where(x => x > 0).ToList();
                }

                //save as new

                TContentType?newCt = null;
                try
                {
                    //This mapping will cause a lot of content type validation to occur which we need to deal with
                    newCt = UmbracoMapper.Map <TContentType>(contentTypeSave);
                }
                catch (Exception ex)
                {
                    TContentTypeDisplay?responseEx =
                        CreateInvalidCompositionResponseException <TContentTypeDisplay, TContentTypeSave, TPropertyType>(
                            ex, contentTypeSave, ct, ctId);
                    if (responseEx is null)
                    {
                        throw ex;
                    }

                    return(ValidationProblem(responseEx));
                }

                TContentTypeDisplay?exResult =
                    CreateCompositionValidationExceptionIfInvalid <TContentTypeSave, TPropertyType, TContentTypeDisplay>(
                        contentTypeSave, newCt);
                if (exResult != null)
                {
                    return(ValidationProblem(exResult));
                }

                //set id to null to ensure its handled as a new type
                contentTypeSave.Id         = null;
                contentTypeSave.CreateDate = DateTime.Now;
                contentTypeSave.UpdateDate = DateTime.Now;

                saveContentType(newCt);

                //we need to save it twice to allow itself under itself.
                if (allowItselfAsChild && newCt != null)
                {
                    newCt.AllowedContentTypes =
                        newCt.AllowedContentTypes?.Union(
                            new[] { new ContentTypeSort(newCt.Id, allowIfselfAsChildSortOrder) }
                            );
                    saveContentType(newCt);
                }

                return(newCt);
            }
        }