/// <summary>
        /// Execute the cmdlet
        /// </summary>
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();


            // Initialize logging instance with Powershell logger
            ITraceLogger logger = new DefaultUsageLogger(LogVerbose, LogWarning, LogError);


            // Construct the model
            var SiteComponents = new SiteProvisionerModel()
            {
                Lists = new List <SPListDefinition>()
            };

            var ctx        = this.ClientContext;
            var contextWeb = this.ClientContext.Web;

            ctx.Load(contextWeb, ctxw => ctxw.ServerRelativeUrl, wctx => wctx.Url, ctxw => ctxw.Id);
            ctx.ExecuteQueryRetry();

            var _targetList = Identity.GetList(contextWeb, lctx => lctx.ItemCount, lctx => lctx.EnableFolderCreation, lctx => lctx.RootFolder, lctx => lctx.RootFolder.ServerRelativeUrl, lctx => lctx.RootFolder.Folders);


            var webUri = new Uri(contextWeb.Url);

            // Will query the list to determine the last item id in the list
            var lastItemId = _targetList.QueryLastItemId();

            logger.LogInformation("List with item count {0} has a last ID of {1}", _targetList.ItemCount, lastItemId);
            logger.LogInformation("List has folder creation = {0}", _targetList.EnableFolderCreation);

            // store the OOTB standard fields
            var ootbCamlFields = new List <string>()
            {
                "Title", "ID", "Author", "Editor", "Created", "Modified"
            };

            // Skip these specific fields
            var skiptypes = new FieldType[]
            {
                FieldType.Invalid,
                FieldType.Computed,
                FieldType.ContentTypeId,
                FieldType.Invalid,
                FieldType.WorkflowStatus,
                FieldType.WorkflowEventType,
                FieldType.Threading,
                FieldType.ThreadIndex,
                FieldType.Recurrence,
                FieldType.PageSeparator,
                FieldType.OutcomeChoice,
                FieldType.CrossProjectLink,
                FieldType.ModStat,
                FieldType.Error,
                FieldType.MaxItems,
                FieldType.Attachments
            };

            // pull a small portion of the list
            // wire up temporary array
            var sitelists = new List <SPListDefinition>()
            {
                ctx.GetListDefinition(_targetList, ExpandObjects, logger, skiptypes)
            };

            if (sitelists.Any())
            {
                var idx = 0;

                // lets add any list with NO lookups first
                var nolookups = sitelists.Where(sl => !sl.ListDependency.Any());
                nolookups.ToList().ForEach(nolookup =>
                {
                    logger.LogInformation("adding list {0}", nolookup.ListName);
                    nolookup.ProvisionOrder = idx++;
                    SiteComponents.Lists.Add(nolookup);
                    sitelists.Remove(nolookup);
                });

                // order with first in stack
                var haslookups = sitelists.Where(sl => sl.ListDependency.Any()).OrderBy(ob => ob.ListDependency.Count()).ToList();
                while (haslookups.Count() > 0)
                {
                    var listPopped = haslookups.FirstOrDefault();
                    haslookups.Remove(listPopped);
                    logger.LogInformation("popping list {0}", listPopped.ListName);

                    if (listPopped.ListDependency.Any(listField => listPopped.ListName.Equals(listField, StringComparison.InvariantCultureIgnoreCase) ||
                                                      listPopped.InternalName.Equals(listField, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        // the list has a dependency on itself
                        logger.LogInformation("Adding list {0} with dependency on itself", listPopped.ListName);
                        listPopped.ProvisionOrder = idx++;
                        SiteComponents.Lists.Add(listPopped);
                    }
                    else if (listPopped.ListDependency.Any(listField =>
                                                           !SiteComponents.Lists.Any(sc => sc.ListName.Equals(listField, StringComparison.InvariantCultureIgnoreCase) ||
                                                                                     sc.InternalName.Equals(listField, StringComparison.InvariantCultureIgnoreCase))))
                    {
                        // no list definition exists in the collection with the dependent lookup lists
                        logger.LogWarning("List {0} depends on {1} which do not exist current collection", listPopped.ListName, string.Join(",", listPopped.ListDependency));
                        foreach (var dependent in listPopped.ListDependency.Where(dlist => !haslookups.Any(hl => hl.ListName == dlist)))
                        {
                            var sitelist           = contextWeb.GetListByTitle(dependent, lctx => lctx.Id, lctx => lctx.Title, lctx => lctx.RootFolder.ServerRelativeUrl);
                            var sitelistDefinition = ctx.GetListDefinition(contextWeb, sitelist, true, logger, skiptypes);
                            haslookups.Add(sitelistDefinition);
                        }

                        haslookups.Add(listPopped); // add back to collection
                        listPopped = null;
                    }
                    else
                    {
                        logger.LogInformation("Adding list {0} to collection", listPopped.ListName);
                        listPopped.ProvisionOrder = idx++;
                        SiteComponents.Lists.Add(listPopped);
                    }
                }
            }

            foreach (var listDefinition in SiteComponents.Lists.OrderBy(ob => ob.ProvisionOrder))
            {
                listDefinition.ListItems = new List <SPListItemDefinition>();

                var camlFields = new List <string>();
                var listTitle  = listDefinition.ListName;
                var etlList    = this.ClientContext.Web.GetListByTitle(listTitle,
                                                                       lctx => lctx.Id, lctx => lctx.ItemCount, lctx => lctx.EnableFolderCreation, lctx => lctx.RootFolder.ServerRelativeUrl);

                if (ExpandObjects)
                {
                    // list fields
                    var listFields = listDefinition.FieldDefinitions;
                    if (listFields != null && listFields.Any())
                    {
                        var filteredListFields = listFields.Where(lf => !skiptypes.Any(st => lf.FieldTypeKind == st)).ToList();
                        var notInCamlFields    = listFields.Where(listField => !ootbCamlFields.Any(cf => cf.Equals(listField.InternalName, StringComparison.CurrentCultureIgnoreCase)) && !skiptypes.Any(st => listField.FieldTypeKind == st));
                        foreach (var listField in notInCamlFields)
                        {
                            logger.LogInformation("Processing list {0} field {1}", etlList.Title, listField.InternalName);
                            camlFields.Add(listField.InternalName);
                        }
                    }
                }

                camlFields.AddRange(ootbCamlFields);
                var camlViewFields = CAML.ViewFields(camlFields.Select(s => CAML.FieldRef(s)).ToArray());


                ListItemCollectionPosition itemPosition = null;
                var camlQueries = etlList.SafeCamlClauseFromThreshold(2000, CamlStatement, 0, lastItemId);
                foreach (var camlAndValue in camlQueries)
                {
                    itemPosition = null;
                    var camlWhereClause = (string.IsNullOrEmpty(camlAndValue) ? string.Empty : CAML.Where(camlAndValue));
                    var camlQuery       = new CamlQuery()
                    {
                        ViewXml = CAML.ViewQuery(
                            ViewScope.RecursiveAll,
                            camlWhereClause,
                            CAML.OrderBy(new OrderByField("ID")),
                            camlViewFields,
                            500)
                    };

                    try
                    {
                        while (true)
                        {
                            logger.LogWarning("CAML Query {0} at position {1}", camlWhereClause, (itemPosition == null ? string.Empty : itemPosition.PagingInfo));
                            camlQuery.ListItemCollectionPosition = itemPosition;
                            var listItems = etlList.GetItems(camlQuery);
                            etlList.Context.Load(listItems);
                            etlList.Context.ExecuteQueryRetry();
                            itemPosition = listItems.ListItemCollectionPosition;

                            foreach (var rbiItem in listItems)
                            {
                                var itemId    = rbiItem.Id;
                                var itemTitle = rbiItem.RetrieveListItemValue("Title");
                                var author    = rbiItem.RetrieveListItemUserValue("Author");
                                var editor    = rbiItem.RetrieveListItemUserValue("Editor");
                                logger.LogInformation("Title: {0}; Item ID: {1}", itemTitle, itemId);

                                var newitem = new SPListItemDefinition()
                                {
                                    Id       = itemId,
                                    Title    = itemTitle,
                                    Created  = rbiItem.RetrieveListItemValue("Created").ToNullableDatetime(),
                                    Modified = rbiItem.RetrieveListItemValue("Modified").ToNullableDatetime()
                                };

                                if (author != null)
                                {
                                    newitem.CreatedBy = new SPPrincipalUserDefinition()
                                    {
                                        Email     = author.ToUserEmailValue(),
                                        LoginName = author.ToUserValue(),
                                        Id        = author.LookupId
                                    };
                                }
                                if (editor != null)
                                {
                                    newitem.ModifiedBy = new SPPrincipalUserDefinition()
                                    {
                                        Email     = editor.ToUserEmailValue(),
                                        LoginName = editor.ToUserValue(),
                                        Id        = editor.LookupId
                                    };
                                }


                                if (ExpandObjects)
                                {
                                    var fieldValuesToWrite = rbiItem.FieldValues.Where(rfield => !ootbCamlFields.Any(oc => rfield.Key.Equals(oc, StringComparison.CurrentCultureIgnoreCase)));
                                    foreach (var rbiField in fieldValuesToWrite)
                                    {
                                        newitem.ColumnValues.Add(new SPListItemFieldDefinition()
                                        {
                                            FieldName  = rbiField.Key,
                                            FieldValue = rbiField.Value
                                        });
                                    }
                                }

                                listDefinition.ListItems.Add(newitem);
                            }

                            if (itemPosition == null)
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "Failed to retrieve list item collection");
                    }
                }
            }


            WriteObject(SiteComponents);
        }
        /// <summary>
        /// Process the request
        /// </summary>
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();

            // Initialize logging instance with Powershell logger
            ITraceLogger logger = new DefaultUsageLogger(LogVerbose, LogWarning, LogError);

            // Skip these specific fields
            var skiptypes = new FieldType[]
            {
                FieldType.Invalid,
                FieldType.Computed,
                FieldType.ContentTypeId,
                FieldType.Invalid,
                FieldType.WorkflowStatus,
                FieldType.WorkflowEventType,
                FieldType.Threading,
                FieldType.ThreadIndex,
                FieldType.Recurrence,
                FieldType.PageSeparator,
                FieldType.OutcomeChoice,
                FieldType.CrossProjectLink,
                FieldType.ModStat,
                FieldType.Error,
                FieldType.MaxItems,
                FieldType.Attachments
            };

            // Definition file to operate on
            SiteProvisionerModel siteDefinition = null;

            try
            {
                // Retreive JSON Provisioner file and deserialize it
                var filePath     = new System.IO.FileInfo(this.ProvisionerFilePath);
                var filePathJSON = System.IO.File.ReadAllText(filePath.FullName);
                siteDefinition = JsonConvert.DeserializeObject <SiteProvisionerModel>(filePathJSON);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Failed to parse {0} Exception {1}", ProvisionerFilePath, ex.Message);
                return;
            }


            // Expectation is that list already exists in target location
            foreach (var customListDefinition in siteDefinition.Lists.OrderBy(ob => ob.ProvisionOrder))
            {
                var etlList = this.ClientContext.Web.GetListByTitle(customListDefinition.ListName,
                                                                    lctx => lctx.Id, lctx => lctx.RootFolder.ServerRelativeUrl, lctx => lctx.Title);
                logger.LogInformation("List {0}", etlList.Title);


                var dataMigratedFieldModel = new SPFieldDefinitionModel(FieldType.Boolean)
                {
                    InternalName     = "DataMigrated",
                    Title            = "DataMigrated",
                    AddToDefaultView = false,
                    AutoIndexed      = true,
                    DefaultValue     = "0",
                    FieldGuid        = new Guid("9a353694-a5b4-4be4-a77a-c67bb071fbb5"),
                    FieldIndexed     = true,
                    GroupName        = "customcolumns"
                };
                var dataMigratedField = etlList.CreateListColumn(dataMigratedFieldModel, logger, null, null);

                var sourceFieldModel = new SPFieldDefinitionModel(FieldType.Integer)
                {
                    InternalName     = "SourceItemID",
                    Title            = "SourceItemID",
                    AddToDefaultView = false,
                    AutoIndexed      = true,
                    FieldGuid        = new Guid("e57a0936-5e8b-45d6-8c1c-d3e971c5b570"),
                    FieldIndexed     = true,
                    GroupName        = "customcolumns"
                };
                var sourceField = etlList.CreateListColumn(sourceFieldModel, logger, null, null);


                // pull the internal names from list definition
                var customFields = customListDefinition.FieldDefinitions
                                   .Where(lf => !skiptypes.Any(st => lf.FieldTypeKind == st))
                                   .Select(s => s.InternalName);
                logger.LogWarning("Processing list {0} found {1} fields to be processed", etlList.Title, customFields.Count());

                // enumerate list items and add them to the list
                if (customListDefinition.ListItems != null && customListDefinition.ListItems.Any())
                {
                    foreach (var item in customListDefinition.ListItems)
                    {
                        var lici    = new ListItemCreationInformation();
                        var newItem = etlList.AddItem(lici);
                        newItem[ConstantsFields.Field_Title] = item.Title;
                        newItem["SourceItemID"] = item.Id;
                        newItem["DataMigrated"] = true;
                        newItem.Update();
                        logger.LogInformation("Processing list {0} Setting up Item {1}", etlList.Title, item.Id);

                        var customColumns = item.ColumnValues.Where(cv => customFields.Any(cf => cf.Equals(cv.FieldName)));
                        foreach (var spRefCol in customColumns)
                        {
                            var internalFieldName = spRefCol.FieldName;
                            var itemColumnValue   = spRefCol.FieldValue;

                            if (IsLookup(customListDefinition, internalFieldName, out SPFieldDefinitionModel strParent))
                            {
                                newItem[internalFieldName] = GetParentItemID(this.ClientContext, itemColumnValue, strParent, logger);
                            }
                            else if (IsUser(customListDefinition, internalFieldName))
                            {
                                newItem[internalFieldName] = GetUserID(this.ClientContext, itemColumnValue, logger);
                            }
                            else
                            {
                                newItem[internalFieldName] = itemColumnValue;
                            }
                            newItem.Update();
                        }
                        etlList.Context.ExecuteQueryRetry();
                    }
                }
            }
        }
        /// <summary>
        /// Builds a Field Creation Info object from the Definition model and returns its resulting XML
        /// </summary>
        /// <param name="host">The instantiated web/list/library to which the field will be added</param>
        /// <param name="fieldDefinition">The definition pulled from a SP Site or user construction</param>
        /// <param name="siteGroups">The collection of site groups that a user/group field make filter</param>
        /// <param name="JsonFilePath">The file path to a JSON file containing Choice lookups</param>
        /// <returns></returns>
        public static string CreateFieldDefinition(this SecurableObject host, SPFieldDefinitionModel fieldDefinition, List <SPGroupDefinitionModel> siteGroups, string JsonFilePath = null)
        {
            var idguid           = fieldDefinition.FieldGuid;
            var choiceXml        = string.Empty;
            var defaultChoiceXml = string.Empty;
            var attributes       = new List <KeyValuePair <string, string> >();

            if (string.IsNullOrEmpty(fieldDefinition.InternalName))
            {
                throw new ArgumentNullException("InternalName");
            }

            if (string.IsNullOrEmpty(fieldDefinition.DisplayName))
            {
                throw new ArgumentNullException("DisplayName");
            }

            if (!string.IsNullOrEmpty(fieldDefinition.LoadFromJSON) && string.IsNullOrEmpty(JsonFilePath))
            {
                throw new ArgumentNullException("JsonFilePath", "You must specify a file path to the JSON file if loading from JSON");
            }

            if (!string.IsNullOrEmpty(fieldDefinition.PeopleGroupName) && (siteGroups == null || siteGroups.Count() <= 0))
            {
                throw new ArgumentNullException("SiteGroups", string.Format("You must specify a collection of group for the field {0}", fieldDefinition.DisplayName));
            }

            if (string.IsNullOrEmpty(fieldDefinition.LookupListName) && fieldDefinition.fieldType == FieldType.Lookup)
            {
                throw new ArgumentNullException("LookupListName", string.Format("you must specify a lookup list title for the field {0}", fieldDefinition.DisplayName));
            }


            if (!string.IsNullOrEmpty(fieldDefinition.Description))
            {
                attributes.Add(new KeyValuePair <string, string>("Description", fieldDefinition.Description));
            }
            if (fieldDefinition.FieldIndexed)
            {
                attributes.Add(new KeyValuePair <string, string>("Indexed", fieldDefinition.FieldIndexed.ToString().ToUpper()));
            }
            if (fieldDefinition.AppendOnly)
            {
                attributes.Add(new KeyValuePair <string, string>("AppendOnly", fieldDefinition.AppendOnly.ToString().ToUpper()));
            }

            var choices = new FieldType[] { FieldType.Choice, FieldType.GridChoice, FieldType.MultiChoice, FieldType.OutcomeChoice };

            if (choices.Any(a => a == fieldDefinition.fieldType))
            {
                if (!string.IsNullOrEmpty(fieldDefinition.LoadFromJSON))
                {
                    var filePath = string.Format("{0}\\{1}", JsonFilePath, fieldDefinition.LoadFromJSON);
                    //#TODO: Check file path
                    var contents = JsonConvert.DeserializeObject <List <SPChoiceModel> >(System.IO.File.ReadAllText(filePath));
                    fieldDefinition.FieldChoices.Clear();
                    fieldDefinition.FieldChoices.AddRange(contents);
                }

                choiceXml = string.Format("<CHOICES>{0}</CHOICES>", string.Join("", fieldDefinition.FieldChoices.Select(s => string.Format("<CHOICE>{0}</CHOICE>", s.Choice.Trim())).ToArray()));
                if (!string.IsNullOrEmpty(fieldDefinition.ChoiceDefault))
                {
                    defaultChoiceXml = string.Format("<Default>{0}</Default>", fieldDefinition.ChoiceDefault);
                }
                if (fieldDefinition.fieldType == FieldType.Choice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Format", fieldDefinition.ChoiceFormat.ToString("f")));
                }
            }
            else if (fieldDefinition.fieldType == FieldType.DateTime)
            {
                if (fieldDefinition.DateFieldFormat.HasValue)
                {
                    attributes.Add(new KeyValuePair <string, string>("DisplayFormat", fieldDefinition.DateFieldFormat.Value.ToString("f")));
                }
            }
            else if (fieldDefinition.fieldType == FieldType.Note)
            {
                attributes.Add(new KeyValuePair <string, string>("RichText", fieldDefinition.RichTextField.ToString().ToUpper()));
                attributes.Add(new KeyValuePair <string, string>("NumLines", fieldDefinition.NumLines.ToString()));
                if (fieldDefinition.RestrictedMode)
                {
                    attributes.Add(new KeyValuePair <string, string>("RestrictedMode", fieldDefinition.RestrictedMode.ToString().ToUpper()));
                }
                else
                {
                    attributes.Add(new KeyValuePair <string, string>("RichTextMode", "FullHtml"));
                    attributes.Add(new KeyValuePair <string, string>("IsolateStyles", true.ToString().ToUpper()));
                }
            }
            else if (fieldDefinition.fieldType == FieldType.User)
            {
                //AllowMultipleValues
                if (fieldDefinition.MultiChoice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Mult", fieldDefinition.MultiChoice.ToString().ToUpper()));
                }
                //SelectionMode
                if (fieldDefinition.PeopleOnly)
                {
                    attributes.Add(new KeyValuePair <string, string>("UserSelectionMode", FieldUserSelectionMode.PeopleOnly.ToString("d")));
                }

                if (!string.IsNullOrEmpty(fieldDefinition.PeopleLookupField))
                {
                    attributes.Add(new KeyValuePair <string, string>("ShowField", fieldDefinition.PeopleLookupField));
                    //fldUser.LookupField = fieldDef.PeopleLookupField;
                }
                if (!string.IsNullOrEmpty(fieldDefinition.PeopleGroupName))
                {
                    var group = siteGroups.FirstOrDefault(f => f.Title == fieldDefinition.PeopleGroupName);
                    if (group != null)
                    {
                        attributes.Add(new KeyValuePair <string, string>("UserSelectionScope", group.Id.ToString()));
                    }
                }
            }
            else if (fieldDefinition.fieldType == FieldType.Lookup)
            {
                var lParentList     = host.GetAssociatedWeb().GetListByTitle(fieldDefinition.LookupListName);
                var strParentListID = lParentList.Id;

                attributes.Add(new KeyValuePair <string, string>("EnforceUniqueValues", false.ToString().ToUpper()));
                attributes.Add(new KeyValuePair <string, string>("List", strParentListID.ToString("B")));
                attributes.Add(new KeyValuePair <string, string>("ShowField", fieldDefinition.LookupListFieldName));
            }

            var finfo = fieldDefinition.ToCreationObject();

            finfo.AdditionalAttributes = attributes;
            var finfoXml = FieldAndContentTypeExtensions.FormatFieldXml(finfo);

            if (!string.IsNullOrEmpty(choiceXml))
            {
                XDocument xd   = XDocument.Parse(finfoXml);
                XElement  root = xd.FirstNode as XElement;
                if (!string.IsNullOrEmpty(defaultChoiceXml))
                {
                    root.Add(XElement.Parse(defaultChoiceXml));
                }
                root.Add(XElement.Parse(choiceXml));
                finfoXml = xd.ToString();
            }

            return(finfoXml);
        }
예제 #4
0
        protected virtual String ParseType(FieldType type) {
            List<String> parsed = new List<String>();

            Length length = type.FirstOrDefault(attribute => attribute is Length) as Length;

            if (type is StringType) {
                parsed.Add(String.Format("VARCHAR({0})", length == null ? 255 : length.Value));
            }
            else if (type is IntegerType) {
                parsed.Add("INTEGER");
            }
            else if (type is DateTimeType) {
                parsed.Add("DATETIME");
            }

            // Enforce NOT NULL and inline primary key when AutoIncrement is used.
            if (type.Any(attribute => attribute is AutoIncrement) == true) {
                parsed.Add("PRIMARY KEY AUTOINCREMENT NOT NULL");
            }
            else if (type.Any(attribute => attribute is Nullable) == false) {
                parsed.Add("NOT NULL");
            }

            return String.Join(" ", parsed);
        }
        /// <summary>
        /// Builds a Field Creation Info object from the Definition model and returns its resulting XML
        /// </summary>
        /// <param name="host">The instantiated web/list/library to which the field will be added</param>
        /// <param name="fieldDefinition">The definition pulled from a SP Site or user construction</param>
        /// <param name="siteGroups">The collection of site groups that a user/group field make filter</param>
        /// <param name="provisionerChoices">(OPTIONAL) The collection of hoice lookups as defined in the serialized JSON file</param>
        /// <returns></returns>
        public static string CreateFieldDefinition(this SecurableObject host, SPFieldDefinitionModel fieldDefinition, List <SPGroupDefinitionModel> siteGroups, List <SiteProvisionerFieldChoiceModel> provisionerChoices = null)
        {
            var idguid            = fieldDefinition.FieldGuid;
            var choiceXml         = string.Empty;
            var defaultChoiceXml  = string.Empty;
            var formulaXml        = string.Empty;
            var fieldReferenceXml = string.Empty;
            var attributes        = new List <KeyValuePair <string, string> >();

            if (string.IsNullOrEmpty(fieldDefinition.InternalName))
            {
                throw new ArgumentNullException("InternalName");
            }

            if (string.IsNullOrEmpty(fieldDefinition.Title))
            {
                throw new ArgumentNullException("DisplayName");
            }

            if (!string.IsNullOrEmpty(fieldDefinition.PeopleGroupName) && (siteGroups == null || siteGroups.Count() <= 0))
            {
                throw new ArgumentNullException("SiteGroups", string.Format("You must specify a collection of group for the field {0}", fieldDefinition.Title));
            }

            if (string.IsNullOrEmpty(fieldDefinition.LookupListName) && fieldDefinition.FieldTypeKind == FieldType.Lookup)
            {
                throw new ArgumentNullException("LookupListName", string.Format("you must specify a lookup list title for the field {0}", fieldDefinition.Title));
            }

            if (fieldDefinition.LoadFromJSON && (provisionerChoices == null || !provisionerChoices.Any(pc => pc.FieldInternalName == fieldDefinition.InternalName)))
            {
                throw new ArgumentNullException("provisionerChoices", string.Format("You must specify a collection of field choices for the field {0}", fieldDefinition.Title));
            }


            if (!string.IsNullOrEmpty(fieldDefinition.Description))
            {
                attributes.Add(new KeyValuePair <string, string>("Description", fieldDefinition.Description.UnescapeXml().EscapeXml(true)));
            }
            if (fieldDefinition.FieldIndexed)
            {
                attributes.Add(new KeyValuePair <string, string>("Indexed", fieldDefinition.FieldIndexed.ToString().ToUpper()));
            }
            if (fieldDefinition.AppendOnly)
            {
                attributes.Add(new KeyValuePair <string, string>("AppendOnly", fieldDefinition.AppendOnly.ToString().ToUpper()));
            }

            var choices = new FieldType[] { FieldType.Choice, FieldType.GridChoice, FieldType.MultiChoice, FieldType.OutcomeChoice };

            if (choices.Any(a => a == fieldDefinition.FieldTypeKind))
            {
                if (fieldDefinition.LoadFromJSON &&
                    (provisionerChoices != null && provisionerChoices.Any(fc => fc.FieldInternalName == fieldDefinition.InternalName)))
                {
                    var choicecontents = provisionerChoices.FirstOrDefault(fc => fc.FieldInternalName == fieldDefinition.InternalName);
                    fieldDefinition.FieldChoices.Clear();
                    fieldDefinition.FieldChoices.AddRange(choicecontents.Choices);
                }

                //AllowMultipleValues
                if (fieldDefinition.MultiChoice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Mult", fieldDefinition.MultiChoice.ToString().ToUpper()));
                }

                choiceXml = string.Format("<CHOICES>{0}</CHOICES>", string.Join("", fieldDefinition.FieldChoices.Select(s => string.Format("<CHOICE>{0}</CHOICE>", s.Choice.Trim())).ToArray()));
                if (!string.IsNullOrEmpty(fieldDefinition.ChoiceDefault))
                {
                    defaultChoiceXml = string.Format("<Default>{0}</Default>", fieldDefinition.ChoiceDefault);
                }
                if (fieldDefinition.FieldTypeKind == FieldType.Choice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Format", fieldDefinition.ChoiceFormat.ToString("f")));
                }
            }
            else if (fieldDefinition.FieldTypeKind == FieldType.DateTime)
            {
                if (fieldDefinition.DateFieldFormat.HasValue)
                {
                    attributes.Add(new KeyValuePair <string, string>("Format", fieldDefinition.DateFieldFormat.Value.ToString("f")));
                }
            }
            else if (fieldDefinition.FieldTypeKind == FieldType.Note)
            {
                attributes.Add(new KeyValuePair <string, string>("RichText", fieldDefinition.RichTextField.ToString().ToUpper()));
                attributes.Add(new KeyValuePair <string, string>("RestrictedMode", fieldDefinition.RestrictedMode.ToString().ToUpper()));
                attributes.Add(new KeyValuePair <string, string>("NumLines", fieldDefinition.NumLines.ToString()));
                if (!fieldDefinition.RestrictedMode)
                {
                    attributes.Add(new KeyValuePair <string, string>("RichTextMode", "FullHtml"));
                    attributes.Add(new KeyValuePair <string, string>("IsolateStyles", true.ToString().ToUpper()));
                }
            }
            else if (fieldDefinition.FieldTypeKind == FieldType.User)
            {
                //AllowMultipleValues
                if (fieldDefinition.MultiChoice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Mult", fieldDefinition.MultiChoice.ToString().ToUpper()));
                }
                //SelectionMode
                if (fieldDefinition.PeopleOnly)
                {
                    attributes.Add(new KeyValuePair <string, string>("UserSelectionMode", FieldUserSelectionMode.PeopleOnly.ToString("d")));
                }

                if (!string.IsNullOrEmpty(fieldDefinition.PeopleLookupField))
                {
                    attributes.Add(new KeyValuePair <string, string>("ShowField", fieldDefinition.PeopleLookupField));
                    //fldUser.LookupField = fieldDef.PeopleLookupField;
                }
                if (!string.IsNullOrEmpty(fieldDefinition.PeopleGroupName))
                {
                    var group = siteGroups.FirstOrDefault(f => f.Title == fieldDefinition.PeopleGroupName);
                    if (group != null)
                    {
                        attributes.Add(new KeyValuePair <string, string>("UserSelectionScope", group.Id.ToString()));
                    }
                }
            }
            else if (fieldDefinition.FieldTypeKind == FieldType.Lookup)
            {
                var lParentList     = host.GetAssociatedWeb().GetListByTitle(fieldDefinition.LookupListName);
                var strParentListID = lParentList.Id;

                attributes.Add(new KeyValuePair <string, string>("EnforceUniqueValues", false.ToString().ToUpper()));
                attributes.Add(new KeyValuePair <string, string>("List", strParentListID.ToString("B")));
                attributes.Add(new KeyValuePair <string, string>("ShowField", fieldDefinition.LookupListFieldName));
                if (fieldDefinition.MultiChoice)
                {
                    attributes.Add(new KeyValuePair <string, string>("Mult", fieldDefinition.MultiChoice.ToString().ToUpper()));
                }
            }
            else if (fieldDefinition.FieldTypeKind == FieldType.Calculated)
            {
                attributes.Add(new KeyValuePair <string, string>("ResultType", fieldDefinition.OutputType.Value.ToString("f")));
                formulaXml        = string.Format("<Formula>{0}</Formula>", fieldDefinition.DefaultFormula.UnescapeXml().EscapeXml());
                fieldReferenceXml = string.Format("<FieldRefs>{0}</FieldRefs>", string.Join("", fieldDefinition.FieldReferences.Select(s => CAML.FieldRef(s.Trim())).ToArray()));
            }

            // construct the XML
            var finfo = fieldDefinition.ToCreationObject();

            finfo.AdditionalAttributes = attributes;
            var finfoXml = FieldAndContentTypeExtensions.FormatFieldXml(finfo);

            if (!string.IsNullOrEmpty(choiceXml))
            {
                XDocument xd   = XDocument.Parse(finfoXml);
                XElement  root = xd.FirstNode as XElement;
                if (!string.IsNullOrEmpty(defaultChoiceXml))
                {
                    root.Add(XElement.Parse(defaultChoiceXml));
                }
                root.Add(XElement.Parse(choiceXml));
                finfoXml = xd.ToString();
            }
            if (!string.IsNullOrEmpty(formulaXml))
            {
                XDocument xd   = XDocument.Parse(finfoXml);
                XElement  root = xd.FirstNode as XElement;
                root.Add(XElement.Parse(formulaXml));
                if (!string.IsNullOrEmpty(fieldReferenceXml))
                {
                    root.Add(XElement.Parse(fieldReferenceXml));
                }
                finfoXml = xd.ToString();
            }

            return(finfoXml);
        }
        /// <summary>
        /// Parse the Field into the portable field definition object
        /// </summary>
        /// <param name="context">The web context in which the field is provisioned</param>
        /// <param name="field">The field from which we are pulling a portable definition</param>
        /// <param name="logger">Injectable logger for writing Trace events</param>
        /// <param name="siteGroups">A collection of SharePoint groups</param>
        /// <param name="schemaXml">(OPTIONAL) the schema xml parsed into an XDocument</param>
        /// <returns></returns>
        public static SPFieldDefinitionModel RetrieveField(this ClientContext context, Field field, ITraceLogger logger, IEnumerable <Group> siteGroups = null, XElement schemaXml = null)
        {
            field.EnsureProperties(
                lft => lft.Id,
                lft => lft.AutoIndexed,
                lft => lft.CanBeDeleted,
                lft => lft.DefaultFormula,
                lft => lft.DefaultValue,
                lft => lft.Group,
                lft => lft.Description,
                lft => lft.EnforceUniqueValues,
                lft => lft.FieldTypeKind,
                lft => lft.Filterable,
                lft => lft.FromBaseType,
                lft => lft.Hidden,
                lft => lft.Indexed,
                lft => lft.InternalName,
                lft => lft.JSLink,
                lft => lft.NoCrawl,
                lft => lft.ReadOnlyField,
                lft => lft.Required,
                lft => lft.SchemaXml,
                lft => lft.Scope,
                lft => lft.Title);

            var fieldModel = new SPFieldDefinitionModel()
            {
                FieldGuid           = field.Id,
                AutoIndexed         = field.AutoIndexed,
                CanBeDeleted        = field.CanBeDeleted,
                DefaultFormula      = field.DefaultFormula,
                DefaultValue        = field.DefaultValue,
                GroupName           = field.Group,
                Description         = field.Description,
                EnforceUniqueValues = field.EnforceUniqueValues,
                FieldTypeKind       = field.FieldTypeKind,
                FromBaseType        = field.FromBaseType,
                Filterable          = field.Filterable,
                HiddenField         = field.Hidden,
                FieldIndexed        = field.Indexed,
                InternalName        = field.InternalName,
                JSLink        = field.JSLink,
                NoCrawl       = field.NoCrawl,
                ReadOnlyField = field.ReadOnlyField,
                Required      = field.Required,
                Scope         = field.Scope,
                Title         = field.Title,
            };

            // if the schemaXML was not passed in, parse it into a node
            if (schemaXml == null)
            {
                var xdoc = XDocument.Parse(field.SchemaXml, LoadOptions.PreserveWhitespace);
                schemaXml = xdoc.Element("Field");
            }

            var fieldTypeFromXml = string.Empty;

            if (schemaXml.Attribute("Type") != null)
            {
                fieldTypeFromXml             = schemaXml.Attribute("Type").Value;
                fieldModel.FieldTypeKindText = fieldTypeFromXml;
            }

            var choices = new FieldType[] { FieldType.Choice, FieldType.GridChoice, FieldType.OutcomeChoice };

            if (field.FieldTypeKind == FieldType.DateTime)
            {
                var fieldCast = (FieldDateTime)field;
                fieldCast.EnsureProperties(
                    fc => fc.DisplayFormat,
                    fc => fc.DateTimeCalendarType,
                    fc => fc.FriendlyDisplayFormat);

                fieldModel.DateFieldFormat = fieldCast.DisplayFormat;
            }
            else if (field.FieldTypeKind == FieldType.Text)
            {
                var fieldCast = (FieldText)field;
                fieldCast.EnsureProperties(
                    fc => fc.MaxLength);

                fieldModel.MaxLength = fieldCast.MaxLength;
            }
            else if (field.FieldTypeKind == FieldType.Note)
            {
                var fieldCast = (FieldMultiLineText)field;
                fieldCast.EnsureProperties(
                    fc => fc.AllowHyperlink,
                    fc => fc.NumberOfLines,
                    fc => fc.AppendOnly,
                    fc => fc.RestrictedMode,
                    fc => fc.RichText);

                fieldModel.NumLines       = fieldCast.NumberOfLines;
                fieldModel.AppendOnly     = fieldCast.AppendOnly;
                fieldModel.RestrictedMode = fieldCast.RestrictedMode;
                fieldModel.RichTextField  = fieldCast.RichText;
            }
            else if (field.FieldTypeKind == FieldType.User)
            {
                var fieldCast = (FieldUser)field;
                fieldCast.EnsureProperties(
                    fc => fc.SelectionMode,
                    fc => fc.SelectionGroup,
                    fc => fc.AllowDisplay,
                    fc => fc.Presence,
                    fc => fc.AllowMultipleValues,
                    fc => fc.IsDependentLookup,
                    fc => fc.IsRelationship,
                    fc => fc.LookupList,
                    fc => fc.LookupField,
                    fc => fc.DependentLookupInternalNames,
                    fc => fc.PrimaryFieldId);

                fieldModel.PeopleLookupField = fieldCast.LookupField;
                fieldModel.PeopleOnly        = (fieldCast.SelectionMode == FieldUserSelectionMode.PeopleOnly);
                fieldModel.MultiChoice       = fieldCast.AllowMultipleValues;

                if (fieldCast.SelectionGroup > 0)
                {
                    var groupId = fieldCast.SelectionGroup;
                    if (siteGroups == null)
                    {
                        siteGroups = context.LoadQuery(context.Web.SiteGroups
                                                       .Where(w => w.Id == groupId).Include(group => group.Id, group => group.Title));
                        context.ExecuteQueryRetry();
                    }

                    if (siteGroups.Any(sg => sg.Id == groupId))
                    {
                        // we loaded this into context earlier
                        var groupObject = siteGroups.FirstOrDefault(fg => fg.Id == groupId);
                        fieldModel.PeopleGroupName = groupObject.Title;
                    }
                }
            }
            else if (field.FieldTypeKind == FieldType.Lookup)
            {
                var fieldCast = (FieldLookup)field;
                fieldCast.EnsureProperties(
                    fc => fc.LookupList,
                    fc => fc.LookupField,
                    fc => fc.LookupWebId,
                    fc => fc.FromBaseType,
                    fc => fc.AllowMultipleValues,
                    fc => fc.IsDependentLookup,
                    fc => fc.IsRelationship,
                    fc => fc.DependentLookupInternalNames,
                    fc => fc.PrimaryFieldId);

                if (!string.IsNullOrEmpty(fieldCast.LookupList))
                {
                    var lookupGuid = fieldCast.LookupList.TryParseGuid(Guid.Empty);
                    if (lookupGuid != Guid.Empty)
                    {
                        var fieldLookup = context.Web.Lists.GetById(lookupGuid);
                        context.Load(fieldLookup, flp => flp.Title);
                        context.ExecuteQueryRetry();

                        fieldModel.LookupListName      = fieldLookup.Title;
                        fieldModel.LookupListFieldName = fieldCast.LookupField;
                    }
                }
                fieldModel.MultiChoice = fieldCast.AllowMultipleValues;
            }
            else if (field.FieldTypeKind == FieldType.Calculated)
            {
                var fieldCast = (FieldCalculated)field;
                fieldCast.EnsureProperties(
                    fc => fc.DateFormat,
                    fc => fc.DisplayFormat,
                    fc => fc.Formula,
                    fc => fc.OutputType,
                    fc => fc.ShowAsPercentage);


                var xfieldReferences = schemaXml.Element("FieldRefs");
                if (xfieldReferences != null)
                {
                    var fieldreferences = new List <string>();
                    var xFields         = xfieldReferences.Elements("FieldRef");
                    if (xFields != null)
                    {
                        foreach (var xFieldName in xFields.Select(s => s.Attribute("Name")))
                        {
                            //   var xFieldName = xField.Attribute("Name");
                            fieldreferences.Add(xFieldName.Value);
                        }
                    }

                    fieldModel.FieldReferences = fieldreferences;
                }

                fieldModel.OutputType     = fieldCast.OutputType;
                fieldModel.DefaultFormula = fieldCast.Formula;
            }
            else if (field.FieldTypeKind == FieldType.URL)
            {
                var fieldCast = (FieldUrl)field;
                fieldCast.EnsureProperties(
                    fc => fc.DisplayFormat);

                fieldModel.UrlFieldFormat = fieldCast.DisplayFormat;
            }
            else if (field.FieldTypeKind == FieldType.MultiChoice)
            {
                var fieldCast = (FieldMultiChoice)field;
                fieldCast.EnsureProperties(
                    fc => fc.Choices,
                    fc => fc.DefaultValue,
                    fc => fc.FillInChoice,
                    fc => fc.Mappings);

                var choiceOptions = fieldCast.Choices.Select(s =>
                {
                    var optionDefault = default(Nullable <bool>);
                    if (!string.IsNullOrEmpty(field.DefaultValue) &&
                        (field.DefaultValue.Equals(s, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        optionDefault = true;
                    }

                    var option = new SPChoiceModel()
                    {
                        Choice        = s,
                        DefaultChoice = optionDefault
                    };
                    return(option);
                }).ToList();

                fieldModel.FieldChoices = choiceOptions;
                fieldModel.MultiChoice  = field.FieldTypeKind == FieldType.MultiChoice;
            }
            else if (choices.Any(a => a == field.FieldTypeKind))
            {
                var fieldCast = (FieldChoice)field;
                fieldCast.EnsureProperties(
                    fc => fc.Choices,
                    fc => fc.DefaultValue,
                    fc => fc.FillInChoice,
                    fc => fc.Mappings,
                    fc => fc.EditFormat);

                var choiceOptions = fieldCast.Choices.Select(s =>
                {
                    var optionDefault = default(Nullable <bool>);
                    if (!string.IsNullOrEmpty(field.DefaultValue) &&
                        (field.DefaultValue.Equals(s, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        optionDefault = true;
                    }

                    var option = new SPChoiceModel()
                    {
                        Choice        = s,
                        DefaultChoice = optionDefault
                    };
                    return(option);
                }).ToList();

                fieldModel.FieldChoices = choiceOptions;
                fieldModel.ChoiceFormat = fieldCast.EditFormat;
                fieldModel.MultiChoice  = field.FieldTypeKind == FieldType.MultiChoice;
            }
            else if (field.FieldTypeKind == FieldType.Invalid &&
                     fieldTypeFromXml.IndexOf("TaxonomyFieldType", StringComparison.InvariantCultureIgnoreCase) > -1)
            {
                var termsetproperties   = schemaXml.Element("Customization").Element("ArrayOfProperty").Elements("Property");
                var termsetpropkeyvalue = new List <KeyValuePair <string, string> >();
                foreach (var termsetproperty in termsetproperties)
                {
                    var termsetname  = termsetproperty.Element("Name");
                    var termsetvalue = termsetproperty.Element("Value");
                    termsetpropkeyvalue.Add(new KeyValuePair <string, string>(termsetname.Value, (termsetvalue != null ? termsetvalue.Value : string.Empty)));
                }

                var termSetId   = termsetpropkeyvalue.First(f => f.Key == "TermSetId");
                var termSetGuid = termSetId.Value.TryParseGuid(Guid.Empty);
                if (termSetGuid != Guid.Empty)
                {
                    var taxonomyDetails = context.GetTaxonomyFieldInfo(logger, termSetGuid);
                    taxonomyDetails.Customization  = termsetpropkeyvalue;
                    fieldModel.TaxonomyInformation = taxonomyDetails;
                }
            }


            return(fieldModel);
        }
예제 #7
0
        protected virtual String ParseType(FieldType type) {
            List<String> parsed = new List<String>();

            Length length = type.FirstOrDefault(attribute => attribute is Length) as Length;
            Unsigned unsigned = type.FirstOrDefault(attribute => attribute is Unsigned) as Unsigned;

            if (type is StringType) {
                parsed.Add(String.Format("VARCHAR({0})", length == null ? 255 : length.Value));
            }
            else if (type is IntegerType) {
                parsed.Add("INT");

                if (unsigned != null) {
                    parsed.Add("UNSIGNED");
                }
            }
            else if (type is DateTimeType) {
                parsed.Add("DATETIME");
            }

            parsed.Add(type.Any(attribute => attribute is Nullable) == true ? "NULL" : "NOT NULL");

            if (type.Any(attribute => attribute is AutoIncrement) == true) {
                parsed.Add("AUTO_INCREMENT");
            }

            return String.Join(" ", parsed);
        }
        /// <summary>
        /// Process the request
        /// </summary>
        public override void ExecuteCmdlet()
        {
            base.ExecuteCmdlet();

            // File Info
            var fileInfo = new System.IO.FileInfo(this.ProvisionerFilePath);

            // Initialize logging instance with Powershell logger
            ITraceLogger logger = new DefaultUsageLogger(LogVerbose, LogWarning, LogError);

            // Skip these specific fields
            var skiptypes = new FieldType[]
            {
                FieldType.Computed,
                FieldType.ContentTypeId,
                FieldType.Invalid,
                FieldType.WorkflowStatus,
                FieldType.WorkflowEventType,
                FieldType.Threading,
                FieldType.ThreadIndex,
                FieldType.Recurrence,
                FieldType.PageSeparator,
                FieldType.OutcomeChoice,
                FieldType.CrossProjectLink,
                FieldType.ModStat,
                FieldType.Error,
                FieldType.MaxItems,
                FieldType.Attachments
            };

            var skipcolumns = new string[]
            {
                "_Hidden",
                "Base Columns",
                "Content Feedback",
                "Core Contact and Calendar Columns",
                "Core Document Columns",
                "Core Task and Issue Columns",
                "Display Template Columns",
                "Document and Record Management Columns",
                "Enterprise Keywords Group",
                "Extended Columns",
                "JavaScript Display Template Columns",
                "Page Layout Columns",
                "Publishing Columns",
                "Reports",
                "Status Indicators",
                "Translation Columns"
            };

            var skipcontenttypes = new string[]
            {
                "_Hidden",
                "Business Intelligence",
                "Community Content Types",
                "Digital Asset Content Types",
                "Display Template Content Types",
                "Document Content Types",
                "Document Set Content Types",
                "Folder Content Types",
                "Content Feedback",
                "Publishing Content Types",
                "Page Layout Content Types",
                "Special Content Types",
                "Group Work Content Types",
                "List Content Types"
            };

            // Construct the model
            var SiteComponents = new SiteProvisionerModel();

            // Load the Context
            var contextWeb = this.ClientContext.Web;

            this.ClientContext.Load(contextWeb, ctxw => ctxw.ServerRelativeUrl, ctxw => ctxw.Id);

            // Get Site/Web fields
            var fields = this.ClientContext.LoadQuery(contextWeb.Fields
                                                      .Include(
                                                          fctx => fctx.Id,
                                                          fctx => fctx.FieldTypeKind,
                                                          fctx => fctx.Group,
                                                          lft => lft.AutoIndexed,
                                                          lft => lft.CanBeDeleted,
                                                          lft => lft.DefaultFormula,
                                                          lft => lft.DefaultValue,
                                                          lft => lft.Description,
                                                          lft => lft.EnforceUniqueValues,
                                                          lft => lft.Filterable,
                                                          lft => lft.FromBaseType,
                                                          lft => lft.Hidden,
                                                          lft => lft.Indexed,
                                                          lft => lft.InternalName,
                                                          lft => lft.JSLink,
                                                          lft => lft.NoCrawl,
                                                          lft => lft.ReadOnlyField,
                                                          lft => lft.Required,
                                                          lft => lft.SchemaXml,
                                                          lft => lft.Scope,
                                                          lft => lft.Title));

            var groupQuery = this.ClientContext.LoadQuery(contextWeb.SiteGroups
                                                          .Include(group => group.Id,
                                                                   group => group.Title,
                                                                   group => group.Description,
                                                                   group => group.AllowRequestToJoinLeave,
                                                                   group => group.AllowMembersEditMembership,
                                                                   group => group.AutoAcceptRequestToJoinLeave,
                                                                   group => group.OnlyAllowMembersViewMembership,
                                                                   group => group.RequestToJoinLeaveEmailSetting));

            var contentTypes = this.ClientContext.LoadQuery(contextWeb.ContentTypes
                                                            .Include(
                                                                ict => ict.Id,
                                                                ict => ict.Group,
                                                                ict => ict.Description,
                                                                ict => ict.Name,
                                                                ict => ict.Hidden,
                                                                ict => ict.JSLink,
                                                                ict => ict.FieldLinks,
                                                                ict => ict.Fields));


            var lists = this.ClientContext.LoadQuery(contextWeb.Lists
                                                     .Include(
                                                         linc => linc.Title,
                                                         linc => linc.Id,
                                                         linc => linc.Description,
                                                         linc => linc.RootFolder.ServerRelativeUrl,
                                                         linc => linc.Hidden,
                                                         linc => linc.OnQuickLaunch,
                                                         linc => linc.BaseTemplate,
                                                         linc => linc.ContentTypesEnabled,
                                                         linc => linc.AllowContentTypes,
                                                         linc => linc.EnableFolderCreation,
                                                         linc => linc.IsApplicationList,
                                                         linc => linc.IsCatalog,
                                                         linc => linc.IsSiteAssetsLibrary,
                                                         linc => linc.IsPrivate,
                                                         linc => linc.IsSystemList,
                                                         lctx => lctx.SchemaXml).Where(w => !w.IsSystemList && !w.IsSiteAssetsLibrary));

            this.ClientContext.ExecuteQueryRetry();

            var weburl = TokenHelper.EnsureTrailingSlash(contextWeb.ServerRelativeUrl);


            if (groupQuery.Any())
            {
                SiteComponents.Groups = new List <SPGroupDefinitionModel>();

                foreach (var group in groupQuery)
                {
                    var model = new SPGroupDefinitionModel()
                    {
                        Id                             = group.Id,
                        Title                          = group.Title,
                        Description                    = group.Description,
                        AllowRequestToJoinLeave        = group.AllowRequestToJoinLeave,
                        AllowMembersEditMembership     = group.AllowMembersEditMembership,
                        AutoAcceptRequestToJoinLeave   = group.AutoAcceptRequestToJoinLeave,
                        OnlyAllowMembersViewMembership = group.OnlyAllowMembersViewMembership,
                        RequestToJoinLeaveEmailSetting = group.RequestToJoinLeaveEmailSetting
                    };

                    SiteComponents.Groups.Add(model);
                }
            }


            if (fields.Any())
            {
                var webfields = new List <SPFieldDefinitionModel>();
                foreach (var field in fields)
                {
                    if (skiptypes.Any(st => field.FieldTypeKind == st) ||
                        skipcolumns.Any(sg => field.Group.Equals(sg, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        continue;
                    }

                    try
                    {
                        var fieldModel = ClientContext.RetrieveField(field, logger, groupQuery);
                        webfields.Add(fieldModel);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.TraceError("Failed to parse field {0} MSG:{1}", field.InternalName, ex.Message);
                    }
                }

                SiteComponents.FieldDefinitions = webfields;
            }


            var contentTypesFieldset = new List <dynamic>();

            if (contentTypes.Any())
            {
                SiteComponents.ContentTypes = new List <SPContentTypeDefinition>();
                foreach (ContentType contenttype in contentTypes)
                {
                    // skip core content types
                    if (skipcontenttypes.Any(sg => contenttype.Group.Equals(sg, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        continue;
                    }

                    contenttype.EnsureProperties(ctp => ctp.Id, ctp => ctp.Group, ctp => ctp.Hidden, ctp => ctp.Description, ctp => ctp.Name, ctp => ctp.FieldLinks);

                    var ctypemodel = new SPContentTypeDefinition()
                    {
                        ContentTypeId    = contenttype.Id.StringValue,
                        ContentTypeGroup = contenttype.Group,
                        Hidden           = contenttype.Hidden,
                        Description      = contenttype.Description,
                        Name             = contenttype.Name
                    };

                    if (contenttype.FieldLinks.Any())
                    {
                        ctypemodel.FieldLinks = new List <SPFieldLinkDefinitionModel>();
                        foreach (FieldLink fieldlink in contenttype.FieldLinks)
                        {
                            ctypemodel.FieldLinks.Add(new SPFieldLinkDefinitionModel()
                            {
                                Id       = fieldlink.Id,
                                Name     = fieldlink.Name,
                                Required = fieldlink.Required,
                                Hidden   = fieldlink.Hidden
                            });

                            contentTypesFieldset.Add(new { ctypeid = contenttype.Id.StringValue, name = fieldlink.Name });
                        }
                    }

                    SiteComponents.ContentTypes.Add(ctypemodel);
                }
            }


            if (lists.Any())
            {
                var sitelists = new List <SPListDefinition>();

                foreach (List list in lists.Where(lwt =>
                                                  (!_filterLists ||
                                                   (_filterLists && SpecificLists.Any(sl => lwt.Title.Equals(sl, StringComparison.InvariantCultureIgnoreCase))))))
                {
                    var listdefinition = ClientContext.GetListDefinition(contextWeb, list, true, logger, skiptypes, groupQuery);
                    sitelists.Add(listdefinition);
                }

                if (sitelists.Any())
                {
                    var idx = 0;
                    SiteComponents.Lists = new List <SPListDefinition>();

                    // lets add any list with NO lookups first
                    var nolookups = sitelists.Where(sl => !sl.ListDependency.Any());
                    nolookups.ToList().ForEach(nolookup =>
                    {
                        logger.LogInformation("adding list {0}", nolookup.ListName);
                        nolookup.ProvisionOrder = idx++;
                        SiteComponents.Lists.Add(nolookup);
                        sitelists.Remove(nolookup);
                    });

                    // order with first in stack
                    var haslookups = sitelists.Where(sl => sl.ListDependency.Any()).OrderBy(ob => ob.ListDependency.Count()).ToList();
                    while (haslookups.Count() > 0)
                    {
                        var listPopped = haslookups.FirstOrDefault();
                        haslookups.Remove(listPopped);
                        logger.LogInformation("adding list {0}", listPopped.ListName);

                        if (listPopped.ListDependency.Any(listField => listPopped.ListName.Equals(listField, StringComparison.InvariantCultureIgnoreCase) ||
                                                          listPopped.InternalName.Equals(listField, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            // the list has a dependency on itself
                            logger.LogInformation("Adding list {0} with dependency on itself", listPopped.ListName);
                            listPopped.ProvisionOrder = idx++;
                            SiteComponents.Lists.Add(listPopped);
                        }
                        else if (listPopped.ListDependency.Any(listField =>
                                                               !SiteComponents.Lists.Any(sc => sc.ListName.Equals(listField, StringComparison.InvariantCultureIgnoreCase) ||
                                                                                         sc.InternalName.Equals(listField, StringComparison.InvariantCultureIgnoreCase))))
                        {
                            // no list definition exists in the collection with the dependent lookup lists
                            logger.LogWarning("List {0} depends on {1} which do not exist current collection", listPopped.ListName, string.Join(",", listPopped.ListDependency));
                            foreach (var dependent in listPopped.ListDependency.Where(dlist => !haslookups.Any(hl => hl.ListName == dlist)))
                            {
                                var sitelist       = contextWeb.GetListByTitle(dependent, lctx => lctx.Id, lctx => lctx.Title, lctx => lctx.RootFolder.ServerRelativeUrl);
                                var listDefinition = ClientContext.GetListDefinition(contextWeb, sitelist, true, logger, skiptypes, groupQuery);
                                haslookups.Add(listDefinition);
                            }

                            haslookups.Add(listPopped); // add back to collection
                            listPopped = null;
                        }
                        else
                        {
                            logger.LogInformation("Adding list {0} to collection", listPopped.ListName);
                            listPopped.ProvisionOrder = idx++;
                            SiteComponents.Lists.Add(listPopped);
                        }
                    }
                }
            }

            // Write the JSON to disc
            var jsonsettings = new JsonSerializerSettings()
            {
                Formatting         = Formatting.Indented,
                Culture            = System.Globalization.CultureInfo.CurrentUICulture,
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
                NullValueHandling  = NullValueHandling.Ignore
            };

            var json = JsonConvert.SerializeObject(SiteComponents, jsonsettings);

            System.IO.File.WriteAllText(fileInfo.FullName, json);
        }