예제 #1
0
        /// <summary>
        /// Process content
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedContentList"></param>
        private static void ProcessContent(HtmlDocument htmlDoc, EmbeddedSchemaField taggedContentList)
        {
            Schema taggedContentSchema = ((EmbeddedSchemaFieldDefinition)taggedContentList.Definition).EmbeddedSchema;

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-content-name]"))
            {
                // Add XHTML namespace to all elements in the content markup
                //
                foreach (var element in node.QuerySelectorAll("*"))
                {
                    element.SetAttributeValue("xmlns", "http://www.w3.org/1999/xhtml");
                }

                var contentName = node.Attributes["data-content-name"].Value;
                if (!IsEntryAlreadyDefined(contentName, taggedContentList))
                {
                    //Logger.Write("Adding content with name: " + contentName, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);
                    var taggedContentXml = new StringBuilder();
                    taggedContentXml.Append("<TaggedContent><name>");
                    taggedContentXml.Append(contentName);
                    taggedContentXml.Append("</name><content>");
                    taggedContentXml.Append(node.InnerHtml);
                    taggedContentXml.Append("</content></TaggedContent>");
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(taggedContentXml.ToString());
                    ItemFields taggedContent = new ItemFields(xmlDoc.DocumentElement, taggedContentSchema);
                    taggedContentList.Values.Add(taggedContent);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Process links
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedLinkList"></param>
        private static void ProcessLinks(HtmlDocument htmlDoc, EmbeddedSchemaField taggedLinkList)
        {
            Schema taggedLinkSchema = ((EmbeddedSchemaFieldDefinition)taggedLinkList.Definition).EmbeddedSchema;

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-link-name]"))
            {
                var linkName = node.Attributes["data-link-name"].Value;
                if (!IsEntryAlreadyDefined(linkName, taggedLinkList))
                {
                    //Logger.Write("Adding link with name: " + linkName, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);
                    var taggedLinkXml = new StringBuilder();
                    taggedLinkXml.Append("<TaggedLink><name>");
                    taggedLinkXml.Append(linkName);
                    taggedLinkXml.Append("</name>");
                    var linkValue = node.Attributes["href"];
                    if (linkValue != null)
                    {
                        taggedLinkXml.Append("<url>");
                        taggedLinkXml.Append(linkValue.Value);
                        taggedLinkXml.Append("</url>");
                    }
                    taggedLinkXml.Append("</TaggedLink>");
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(taggedLinkXml.ToString());
                    ItemFields taggedLinks = new ItemFields(xmlDoc.DocumentElement, taggedLinkSchema);
                    taggedLinkList.Values.Add(taggedLinks);
                }
            }
        }
        /// <summary>
        /// Process content
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedContentList"></param>
        private static void ProcessContent(HtmlDocument htmlDoc, EmbeddedSchemaField taggedContentList)
        {
            Schema taggedContentSchema = ((EmbeddedSchemaFieldDefinition)taggedContentList.Definition).EmbeddedSchema;

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-content-name]"))
            {
                // Add XHTML namespace to all elements in the content markup
                //
                foreach (var element in node.QuerySelectorAll("*"))
                {
                    element.SetAttributeValue("xmlns", "http://www.w3.org/1999/xhtml");
                }

                var taggedContentXml = new StringBuilder();
                taggedContentXml.Append("<TaggedContent><name>");
                taggedContentXml.Append(node.Attributes["data-content-name"].Value);
                taggedContentXml.Append("</name><content>");
                taggedContentXml.Append(node.InnerHtml);
                taggedContentXml.Append("</content></TaggedContent>");
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(taggedContentXml.ToString());
                ItemFields taggedContent = new ItemFields(xmlDoc.DocumentElement, taggedContentSchema);
                taggedContentList.Values.Add(taggedContent);
            }
        }
        /// <summary>
        /// On Component Save
        /// </summary>
        /// <param name="component"></param>
        /// <param name="args"></param>
        /// <param name="phase"></param>
        public static void OnComponentSave(Component component, SaveEventArgs args, EventPhases phase)
        {
            // TODO: Have a better way of detecting the campaign content zip
            // TODO: Refactor into smaller methods

            if (component.ComponentType == ComponentType.Multimedia && component.MetadataSchema.Title.Equals("Campaign Content ZIP"))
            {
                ItemFields          content            = new ItemFields(component.Metadata, component.MetadataSchema);
                EmbeddedSchemaField taggedContentList  = (EmbeddedSchemaField)content["taggedContent"];
                EmbeddedSchemaField taggedImageList    = (EmbeddedSchemaField)content["taggedImages"];
                EmbeddedSchemaField taggedPropertyList = (EmbeddedSchemaField)content["taggedProperties"];

                var orgItem = component.OrganizationalItem;

                if (taggedContentList.Values.Count > 0 || taggedImageList.Values.Count > 0)
                {
                    // Just do the extraction of content fields from the HTML the first time
                    //
                    return;
                }

                // Extract ZIP and find the index.html
                //
                var zipFilename = Path.GetTempPath() + "\\CampaignContent_" + component.Id.ItemId + "_" + DateTime.Now.ToFileTime() + ".zip";
                Logger.Write("Extracting ZIP: " + zipFilename, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);
                using (FileStream fs = File.Create(zipFilename))
                {
                    component.BinaryContent.WriteToStream(fs);
                }

                string html = null;
                using (ZipArchive archive = ZipFile.Open(zipFilename, ZipArchiveMode.Update))
                {
                    ZipArchiveEntry entry = archive.GetEntry("index.html");

                    using (StreamReader reader = new StreamReader(entry.Open()))
                    {
                        html = reader.ReadToEnd();
                    }

                    if (html != null)
                    {
                        // Parse the HTML and find all content items
                        //
                        var htmlDoc = new HtmlDocument();
                        htmlDoc.LoadHtml(html);
                        htmlDoc.OptionOutputAsXml = true;

                        ProcessContent(htmlDoc, taggedContentList);
                        ProcessImages(htmlDoc, taggedImageList, orgItem, component.Title, archive);
                        ProcessProperties(htmlDoc, taggedPropertyList);

                        component.Metadata = content.ToXml();
                        component.Save();
                    }
                }
                File.Delete(zipFilename);
            }
        }
예제 #5
0
        /// <summary>
        /// Process properties
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedPropertyList"></param>
        private static void ProcessProperties(HtmlDocument htmlDoc, EmbeddedSchemaField taggedPropertyList)
        {
            Schema taggedPropertySchema = ((EmbeddedSchemaFieldDefinition)taggedPropertyList.Definition).EmbeddedSchema;

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-property-name]"))
            {
                //Logger.Write("Processing property tag...", "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);

                int    index       = 1;
                string indexSuffix = "";
                while (true)
                {
                    if (!node.Attributes.Contains("data-property-name" + indexSuffix) ||
                        !node.Attributes.Contains("data-property-target" + indexSuffix))
                    {
                        break;
                    }
                    var propertyName = node.Attributes["data-property-name" + indexSuffix];
                    if (!IsEntryAlreadyDefined(propertyName.Value, taggedPropertyList))
                    {
                        var propertyTarget = node.Attributes["data-property-target" + indexSuffix];
                        if (propertyTarget == null)
                        {
                            Logger.Write("Missing property target for property '" + propertyName.Value + "'. Skpping property...", "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Warning);
                            continue;
                        }

                        //Logger.Write("Adding property with name: " + propertyName.Value, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);

                        var propertyValue = node.Attributes[propertyTarget.Value];

                        var taggedPropertyXml = new StringBuilder();
                        taggedPropertyXml.Append("<TaggedProperty xmlns:xlink=\"http://www.w3.org/1999/xlink\"><name>");
                        taggedPropertyXml.Append(propertyName.Value);
                        taggedPropertyXml.Append("</name><value>");
                        taggedPropertyXml.Append(propertyValue.Value);
                        taggedPropertyXml.Append("</value>");
                        if (index > 1)
                        {
                            taggedPropertyXml.Append("<index>");
                            taggedPropertyXml.Append(index);
                            taggedPropertyXml.Append("</index>");
                        }
                        taggedPropertyXml.Append("<target>");
                        taggedPropertyXml.Append(propertyTarget.Value);
                        taggedPropertyXml.Append("</target></TaggedProperty>");

                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(taggedPropertyXml.ToString());
                        ItemFields taggedProperty = new ItemFields(xmlDoc.DocumentElement, taggedPropertySchema);
                        taggedPropertyList.Values.Add(taggedProperty);
                    }

                    index++;
                    indexSuffix = "-" + index;
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Retrieves multiple <see cref="T:Tridion.ContentManager.ContentManagement.Fields.ItemFields" /> field values.
        /// </summary>
        /// <param name="itemField"><see cref="T:Tridion.ContentManager.ContentManagement.Fields.ItemField" /></param>
        /// <returns><see cref="T:Tridion.ContentManager.ContentManagement.Fields.ItemFields" /> values</returns>
        public static IList <ItemFields> EmbeddedValues(this ItemField itemField)
        {
            if (itemField != null)
            {
                EmbeddedSchemaField field = itemField as EmbeddedSchemaField;

                if (field != null && field.Values.Count > 0)
                {
                    return(field.Values);
                }
            }

            return(new List <ItemFields>());
        }
예제 #7
0
 /// <summary>
 /// Is entry already defined
 /// </summary>
 /// <param name="entryName"></param>
 /// <param name="esField"></param>
 /// <returns></returns>
 private static bool IsEntryAlreadyDefined(string entryName, EmbeddedSchemaField esField)
 {
     foreach (var value in esField.Values)
     {
         if (value.Contains("name"))
         {
             var name = value["name"].ToString();
             if (name.Equals(entryName))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
 private static bool CheckIfEmbeddedFieldHasValues(EmbeddedSchemaField sField)
 {
     //This is a deeper check to see if an embedded schema field has values
     //as the count of values can be greater than zero, but the values themselves not
     //contain any subvalues (so be empty)
     if (sField != null && sField.Values != null && sField.Values.Count > 0)
     {
         foreach (var val in sField.Values)
         {
             var valCount = val.ToXml().ChildNodes.Count;
             if (valCount > 0)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #9
0
        private List <RegionConstraints> GetRegionConstraints()
        {
            List <RegionConstraints> constraints = new List <RegionConstraints>();

            if (_regionMeta == null)
            {
                _regionMeta = GetKeywordMetadata();
            }
            EmbeddedSchemaField schematemplatepairs = (EmbeddedSchemaField)_regionMeta["schematemplatepairs"];

            foreach (ItemFields fields in schematemplatepairs.Values)
            {
                RegionConstraints rc = new RegionConstraints
                {
                    SchemaId            = ResolveUrl(fields["schema"]),
                    ComponentTemplateId = ResolveUrl(fields["template"])
                };
                constraints.Add(rc);
            }
            return(constraints);
        }
예제 #10
0
        /// <summary>
        /// Process images
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedImageList"></param>
        /// <param name="parentFolder"></param>
        /// <param name="componentTitle"></param>
        /// <param name="archive"></param>
        private static void ProcessImages(HtmlDocument htmlDoc, EmbeddedSchemaField taggedImageList, OrganizationalItem parentFolder, String componentTitle, ZipArchive archive)
        {
            EmbeddedSchemaFieldDefinition taggedImageField = (EmbeddedSchemaFieldDefinition)taggedImageList.Definition;
            Schema       taggedImageSchema               = taggedImageField.EmbeddedSchema;
            SchemaFields taggedImageSchemaFields         = new SchemaFields(taggedImageSchema);
            MultimediaLinkFieldDefinition mmLinkFieldDef = (MultimediaLinkFieldDefinition)taggedImageSchemaFields.Fields.Where(field => field.Name.Equals("image")).First();
            Schema imageSchema = mmLinkFieldDef.AllowedTargetSchemas[0];
            Folder imageFolder = null;

            var taggedImageNames     = new List <string>();
            var foundImages          = new Dictionary <string, Component>();
            var imageFolderWebDavUrl = parentFolder.WebDavUrl + "/" + componentTitle + " Images";

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-image-name]"))
            {
                var imageUrl = node.Attributes["src"];

                //Logger.Write("Processing image tag...", "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);

                var taggedImageName = node.Attributes["data-image-name"];
                if (imageUrl != null && taggedImageName != null && !taggedImageNames.Contains(taggedImageName.Value) && !IsEntryAlreadyDefined(taggedImageName.Value, taggedImageList))
                {
                    //Logger.Write("Adding image with name: " + taggedImageName.Value, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);

                    if (imageUrl != null && !imageUrl.Value.StartsWith("http"))
                    {
                        if (imageFolder == null)
                        {
                            if (parentFolder.Session.IsExistingObject(imageFolderWebDavUrl))
                            {
                                imageFolder = (Folder)parentFolder.Session.GetObject(imageFolderWebDavUrl);
                            }
                            else
                            {
                                // Create folder
                                //
                                imageFolder       = new Folder(parentFolder.Session, parentFolder.Id);
                                imageFolder.Title = componentTitle + " Images";
                                imageFolder.Save();
                            }
                        }
                    }

                    // If an absolute image URL
                    //
                    else if (imageUrl != null && imageUrl.Value.StartsWith("http"))
                    {
                        var    url        = imageUrl.Value;
                        string parameters = null;
                        if (url.Contains("?"))
                        {
                            var parts = url.Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries);
                            url        = parts[0];
                            parameters = parts[1];
                        }
                        var taggedImageXml = new StringBuilder();
                        taggedImageXml.Append("<TaggedImage xmlns:xlink=\"http://www.w3.org/1999/xlink\"><name>");
                        taggedImageXml.Append(taggedImageName.Value);
                        taggedImageXml.Append("</name><imageUrl>");
                        taggedImageXml.Append(SecurityElement.Escape(url));
                        taggedImageXml.Append("</imageUrl>");
                        if (parameters != null)
                        {
                            taggedImageXml.Append("<parameters>");
                            taggedImageXml.Append(SecurityElement.Escape(parameters));
                            taggedImageXml.Append("</parameters>");
                        }
                        taggedImageXml.Append("</TaggedImage>");

                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(taggedImageXml.ToString());
                        ItemFields taggedImage = new ItemFields(xmlDoc.DocumentElement, taggedImageSchema);
                        taggedImageList.Values.Add(taggedImage);
                        taggedImageNames.Add(taggedImageName.Value);
                        continue;
                    }
                    ZipArchiveEntry imageEntry = archive.GetEntry(imageUrl.Value);
                    if (imageEntry != null)
                    {
                        Component imageComponent;
                        if (foundImages.TryGetValue(imageUrl.Value, out imageComponent) == false)
                        {
                            var imageName      = Path.GetFileName(imageUrl.Value);
                            var imageWebDavUri = imageFolderWebDavUrl + "/" + imageName;
                            if (parentFolder.Session.IsExistingObject(imageWebDavUri))
                            {
                                imageComponent = (Component)parentFolder.Session.GetObject(imageWebDavUri);
                            }
                            else
                            {
                                imageComponent = new Component(parentFolder.Session, imageFolder.Id);
                                var metadataXml = new XmlDocument();
                                metadataXml.LoadXml("<Metadata xmlns=\"" + imageSchema.NamespaceUri + "\"/>");
                                imageComponent.Schema   = imageSchema;
                                imageComponent.Metadata = metadataXml.DocumentElement;

                                var extension = Path.GetExtension(imageUrl.Value);
                                imageComponent.Title = imageName.Replace(extension, ""); // Set title without extension
                                extension            = extension.ToLower().Replace(".", "");

                                bool foundMMType = false;
                                foreach (var mmType in imageSchema.AllowedMultimediaTypes)
                                {
                                    if (mmType.FileExtensions.Contains(extension))
                                    {
                                        imageComponent.BinaryContent.MultimediaType = mmType;
                                        foundMMType = true;
                                        break;
                                    }
                                }
                                if (!foundMMType)
                                {
                                    Logger.Write("Could not find multimedia type for image extension: " + extension, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Error);
                                }

                                imageComponent.BinaryContent.UploadFromStream = imageEntry.Open();
                                imageComponent.BinaryContent.Filename         = imageName;
                                imageComponent.Save(true);
                            }
                            foundImages.Add(imageUrl.Value, imageComponent);
                        }
                        var taggedImageXml = new StringBuilder();
                        taggedImageXml.Append("<TaggedImage xmlns:xlink=\"http://www.w3.org/1999/xlink\"><name>");
                        taggedImageXml.Append(taggedImageName.Value);
                        taggedImageXml.Append("</name><image xlink:type=\"simple\" xlink:href=\"");
                        taggedImageXml.Append(imageComponent.Id);
                        taggedImageXml.Append("\" xlink:title=\"");
                        taggedImageXml.Append(imageComponent.Title);
                        taggedImageXml.Append("\" /></TaggedImage>");

                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(taggedImageXml.ToString());
                        ItemFields taggedImage = new ItemFields(xmlDoc.DocumentElement, taggedImageSchema);
                        taggedImageList.Values.Add(taggedImage);
                        taggedImageNames.Add(taggedImageName.Value);
                    }
                }
            }
        }
예제 #11
0
 private static bool CheckIfEmbeddedFieldHasValues(EmbeddedSchemaField sField)
 {
     //This is a deeper check to see if an embedded schema field has values
     //as the count of values can be greater than zero, but the values themselves not
     //contain any subvalues (so be empty)
     if (sField != null && sField.Values != null && sField.Values.Count > 0)
     {
         foreach (var val in sField.Values)
         {
             var valCount = val.ToXml().ChildNodes.Count;
             if (valCount > 0)
             {
                 return true;
             }
         }
     }
     return false;
 }
예제 #12
0
        private List <Component> GatherLinkedComponents(Component component)
        {
            _log.Debug($"Gathering linked components for component {component.Title}");
            List <ItemFields> fieldList  = new List <ItemFields>();
            List <Component>  components = new List <Component>();

            if (component.Content != null)
            {
                fieldList.Add(new ItemFields(component.Content, component.Schema));
            }
            if (component.Metadata != null)
            {
                fieldList.Add(new ItemFields(component.Metadata, component.MetadataSchema));
            }
            var componentLinkFields  = new List <ComponentLinkField>();
            var embeddedSchemaFields = new List <EmbeddedSchemaField>();

            foreach (var fields in fieldList)
            {
                foreach (var field in fields)
                {
                    if (field is ComponentLinkField)
                    {
                        componentLinkFields.Add((ComponentLinkField)field);
                    }

                    if (field is EmbeddedSchemaField)
                    {
                        embeddedSchemaFields.Add((EmbeddedSchemaField)field);
                    }
                }
            }

            for (int i = 0; i < embeddedSchemaFields.Count; i++)
            {
                EmbeddedSchemaField           linkField            = embeddedSchemaFields[i];
                EmbeddedSchemaFieldDefinition linksFieldDefinition = linkField.Definition as EmbeddedSchemaFieldDefinition;
                if (linksFieldDefinition?.EmbeddedSchema == null)
                {
                    continue;
                }
                TcmUri id = linksFieldDefinition.EmbeddedSchema.Id; // force schema load
                foreach (var embeddedFields in linkField.Values)
                {
                    foreach (var embeddedField in embeddedFields)
                    {
                        if (embeddedField is ComponentLinkField)
                        {
                            componentLinkFields.Add((ComponentLinkField)embeddedField);
                        }
                        if (embeddedField is EmbeddedSchemaField)
                        {
                            embeddedSchemaFields.Add((EmbeddedSchemaField)embeddedField);
                        }
                    }
                }
            }

            foreach (var linkField in componentLinkFields)
            {
                if (linkField.Values != null)
                {
                    components.AddRange(linkField.Values);
                }
            }
            return(components);
        }
 /// <summary>
 /// Adds the metadata attributes from the page or structure group.
 /// </summary>
 /// <param name="fields">ItemFields collection containing the metadata fields & values.</param>
 /// <param name="writer">The XmlWriter.</param>
 /// <param name="prefix">The prefix to use - leave blank, it will be used when fields are embedded.</param>
 /// <remarks>This method will write values in the navigation XML output from the Page or StructureGroup metadata. Note that it will only include these values if Navigation.IncludePageMetadata or Navigation.IncludeStructureGroupMetadata are set to true. </remarks>
 private void AddMetadataAttributes(IEnumerable <ItemField> fields, XmlWriter writer, string prefix = null)
 {
     foreach (ItemField itemField in fields)
     {
         if (itemField is TextField || itemField is KeywordField)
         {
             bool   includeField  = false;
             string attributeName = null;
             if (Navigation.FieldsToInclude.Count == 0) //  Include all fields
             {
                 includeField  = true;
                 attributeName = itemField.Name.ToLower();
             }
             else if (Navigation.FieldsToInclude.ContainsKey(itemField.Name))
             {
                 includeField  = true;
                 attributeName = Navigation.FieldsToInclude[itemField.Name];
             }
             else
             {
                 _log.Debug("Not including field " + itemField.Name + " because it is not in the list of Navigation.FieldsToInclude");
             }
             if (includeField)
             {
                 if (prefix != null)
                 {
                     attributeName = prefix + attributeName;
                 }
                 if (itemField is TextField)
                 {
                     TextField field = (TextField)itemField;
                     if (field.Values.Count > 0)
                     {
                         writer.WriteAttributeString(attributeName, field.Value);
                     }
                 }
                 if (itemField is KeywordField)
                 {
                     KeywordField field = (KeywordField)itemField;
                     if (field.Values.Count > 0)
                     {
                         writer.WriteAttributeString(attributeName, field.Value.Title);
                     }
                 }
                 _countFields++;
             }
         }
         else if (itemField is EmbeddedSchemaField)
         {
             EmbeddedSchemaField embedded = (EmbeddedSchemaField)itemField;
             int count = 0;
             foreach (ItemFields embeddedFields in embedded.Values)
             {
                 AddMetadataAttributes(embeddedFields, writer, embedded.Name + count);
                 count++;
             }
         }
         else
         {
             _log.Debug("Not adding metadata for field " + itemField.Name + " since it is not a Text Field.");
         }
     }
 }
        /// <summary>
        /// Process images
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="taggedImageList"></param>
        /// <param name="parentFolder"></param>
        /// <param name="componentTitle"></param>
        /// <param name="archive"></param>
        private static void ProcessImages(HtmlDocument htmlDoc, EmbeddedSchemaField taggedImageList, OrganizationalItem parentFolder, String componentTitle, ZipArchive archive)
        {
            EmbeddedSchemaFieldDefinition taggedImageField = (EmbeddedSchemaFieldDefinition)taggedImageList.Definition;
            Schema       taggedImageSchema               = taggedImageField.EmbeddedSchema;
            SchemaFields taggedImageSchemaFields         = new SchemaFields(taggedImageSchema);
            MultimediaLinkFieldDefinition mmLinkFieldDef = (MultimediaLinkFieldDefinition)taggedImageSchemaFields.Fields[1];
            Schema imageSchema = mmLinkFieldDef.AllowedTargetSchemas[0];
            Folder imageFolder = null;

            var taggedImageNames = new List <string>();
            var foundImages      = new Dictionary <string, Component>();

            foreach (var node in htmlDoc.DocumentNode.QuerySelectorAll("[data-image-name]"))
            {
                if (imageFolder == null)
                {
                    imageFolder       = new Folder(parentFolder.Session, parentFolder.Id);
                    imageFolder.Title = componentTitle + " " + "Images";
                    imageFolder.Save();
                }

                //Logger.Write("Processing image tag...", "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);

                var imageUrl        = node.Attributes["src"];
                var taggedImageName = node.Attributes["data-image-name"];
                if (imageUrl != null && taggedImageName != null && !taggedImageNames.Contains(taggedImageName.Value))
                {
                    ZipArchiveEntry imageEntry = archive.GetEntry(imageUrl.Value);
                    if (imageEntry != null)
                    {
                        Component imageComponent;
                        if (foundImages.TryGetValue(imageUrl.Value, out imageComponent) == false)
                        {
                            imageComponent = new Component(parentFolder.Session, imageFolder.Id);
                            var imageName   = Path.GetFileName(imageUrl.Value);
                            var metadataXml = new XmlDocument();
                            metadataXml.LoadXml("<Metadata xmlns=\"" + imageSchema.NamespaceUri + "\"/>");
                            imageComponent.Schema   = imageSchema;
                            imageComponent.Metadata = metadataXml.DocumentElement;
                            imageComponent.Title    = imageName;

                            var  extension   = Path.GetExtension(imageUrl.Value).ToLower();
                            bool foundMMType = false;
                            foreach (var mmType in imageSchema.AllowedMultimediaTypes)
                            {
                                if (mmType.FileExtensions.Contains(extension))
                                {
                                    imageComponent.BinaryContent.MultimediaType = mmType;
                                    foundMMType = true;
                                    break;
                                }
                            }
                            if (!foundMMType)
                            {
                                Logger.Write("Could not find multimedia type for image extension: " + extension, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Error);
                            }

                            imageComponent.BinaryContent.UploadFromStream = imageEntry.Open();
                            imageComponent.BinaryContent.Filename         = imageName;
                            imageComponent.Save(true);
                            foundImages.Add(imageUrl.Value, imageComponent);
                        }
                        var taggedImageXml = new StringBuilder();
                        taggedImageXml.Append("<TaggedImage xmlns:xlink=\"http://www.w3.org/1999/xlink\"><name>");
                        taggedImageXml.Append(taggedImageName.Value);
                        taggedImageXml.Append("</name><image xlink:type=\"simple\" xlink:href=\"");
                        taggedImageXml.Append(imageComponent.Id);
                        taggedImageXml.Append("\" xlink:title=\"");
                        taggedImageXml.Append(imageComponent.Title);
                        taggedImageXml.Append("\" /></TaggedImage>");

                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.LoadXml(taggedImageXml.ToString());
                        ItemFields taggedImage = new ItemFields(xmlDoc.DocumentElement, taggedImageSchema);
                        taggedImageList.Values.Add(taggedImage);
                        taggedImageNames.Add(taggedImageName.Value);
                    }
                }
            }
        }
예제 #15
0
        /// <summary>
        /// On Component Save
        /// </summary>
        /// <param name="component"></param>
        /// <param name="args"></param>
        /// <param name="phase"></param>
        public static void OnComponentSave(Component component, SaveEventArgs args, EventPhases phase)
        {
            // TODO: Have a better way of detecting the campaign content zip

            if (component.ComponentType == ComponentType.Multimedia && component.MetadataSchema.Title.Equals("Campaign Content ZIP") && !component.BinaryContent.Filename.Contains(".Processed"))
            {
                ItemFields          content            = new ItemFields(component.Metadata, component.MetadataSchema);
                EmbeddedSchemaField taggedContentList  = (EmbeddedSchemaField)content["taggedContent"];
                EmbeddedSchemaField taggedImageList    = (EmbeddedSchemaField)content["taggedImages"];
                EmbeddedSchemaField taggedPropertyList = (EmbeddedSchemaField)content["taggedProperties"];
                EmbeddedSchemaField taggedLinkList     = (EmbeddedSchemaField)content["taggedLinks"];

                var orgItem = component.OrganizationalItem;

                /* TODO: Can we control this via a setting? We could upload an optional add-on configuration
                 * if ( taggedContentList.Values.Count > 0 || taggedImageList.Values.Count > 0 )
                 * {
                 *  // Just do the extraction of content fields from the HTML the first time
                 *  //
                 *  return;
                 * }
                 */

                // Extract ZIP and find the index.html
                //
                var zipFilename = Path.GetTempPath() + "\\CampaignContent_" + component.Id.ItemId + "_" + DateTime.Now.ToFileTime() + ".zip";
                Logger.Write("Extracting Campaign ZIP: " + zipFilename, "CampaignZipImporter", LogCategory.Custom, System.Diagnostics.TraceEventType.Information);
                using (FileStream fs = File.Create(zipFilename))
                {
                    component.BinaryContent.WriteToStream(fs);
                }

                string html = null;
                using (ZipArchive archive = ZipFile.Open(zipFilename, ZipArchiveMode.Update))
                {
                    ZipArchiveEntry entry = archive.GetEntry("index.html");
                    if (entry == null)
                    {
                        throw new Exception("Missing index.html in the campaign ZIP!");
                    }
                    using (StreamReader reader = new StreamReader(entry.Open()))
                    {
                        html = reader.ReadToEnd();
                    }

                    if (html != null)
                    {
                        // Parse the HTML and find all content items
                        //
                        var htmlDoc = new HtmlDocument();
                        htmlDoc.LoadHtml(html);
                        htmlDoc.OptionOutputAsXml = true;

                        ProcessContent(htmlDoc, taggedContentList);
                        ProcessImages(htmlDoc, taggedImageList, orgItem, component.Title, archive);
                        ProcessProperties(htmlDoc, taggedPropertyList);
                        ProcessLinks(htmlDoc, taggedLinkList);

                        component.Metadata = content.ToXml();

                        // Mark the ZIP file processed. This avoid processing the ZIP file each time there is change in the content section.
                        //
                        var filename = component.BinaryContent.Filename;
                        int dotIndex = filename.LastIndexOf(".");
                        if (dotIndex == -1)
                        {
                            filename += ".Processed";
                        }
                        else
                        {
                            filename = filename.Insert(dotIndex, ".Processed");
                        }
                        component.BinaryContent.Filename = filename;

                        component.Save();
                    }
                }
                File.Delete(zipFilename);
            }
        }
예제 #16
0
 private void OutputEmbeddedValues(EmbeddedSchemaField field, StringBuilder sb)
 {
     if (field.Values.Count() == 0)
     {
         sb.Append("<empty/>\n");
         return;
     }
     foreach (ItemFields embeddedValue in field.Values)
     {
         sb.Append("<embedded>\n");
         this.OutputFields(embeddedValue, sb);
         sb.Append("</embedded>\n");
     }
 }
        /// <summary>
        /// Populates the dictionary with values from the item fields.
        /// </summary>
        /// <param name="itemFields">The Tridion itemfields to populate the dictionary with.</param>
        private void PopulateDynamicItemFields(ItemFields itemFields)
        {
            if (itemFields == null)
            {
                return;
            }

            foreach (ItemField itemField in itemFields)
            {
                string key = itemField.Name.ToLower();

                if (itemField is XhtmlField)
                {
                    XhtmlField xhtmlField = (XhtmlField)itemField;
                    if (xhtmlField.Definition.MaxOccurs == 1)
                    {
                        _dictionary[key] = TemplateUtilities.ResolveRichTextFieldXhtml(xhtmlField.Value);
                    }
                    else
                    {
                        List <string> values = new List <string>();
                        foreach (string value in xhtmlField.Values)
                        {
                            values.Add(TemplateUtilities.ResolveRichTextFieldXhtml(value));
                        }
                        _dictionary[key] = values;
                    }
                }
                else if (itemField is TextField)
                {
                    TextField textField = (TextField)itemField;
                    if (textField.Definition.MaxOccurs == 1)
                    {
                        _dictionary[key] = textField.Value;
                    }
                    else
                    {
                        _dictionary[key] = textField.Values;
                    }
                }
                else if (itemField is DateField)
                {
                    DateField dateField = (DateField)itemField;
                    if (dateField.Definition.MaxOccurs == 1)
                    {
                        _dictionary[key] = dateField.Value;
                    }
                    else
                    {
                        _dictionary[key] = dateField.Values;
                    }
                }
                else if (itemField is KeywordField)
                {
                    KeywordField keywordField = (KeywordField)itemField;
                    if (keywordField.Definition.MaxOccurs == 1)
                    {
                        if (keywordField.Value == null)
                        {
                            _dictionary[key] = null;
                        }
                        else
                        {
                            _dictionary[key] = new KeywordModel(_engine, keywordField.Value);
                        }
                    }
                    else
                    {
                        List <KeywordModel> keywords = new List <KeywordModel>();
                        int i = 0;
                        foreach (Keyword k in keywordField.Values)
                        {
                            var kw = new KeywordModel(_engine, k);
                            kw.Index  = i++;
                            kw.IsLast = Index == keywordField.Values.Count - 1;
                            keywords.Add(kw);
                        }
                        _dictionary[key] = keywords;
                    }
                }
                else if (itemField is EmbeddedSchemaField)
                {
                    EmbeddedSchemaField embeddedSchemaField = (EmbeddedSchemaField)itemField;
                    if (embeddedSchemaField.Definition.MaxOccurs == 1)
                    {
                        if (embeddedSchemaField.Values.Count == 0)
                        {
                            _dictionary[key] = null;
                        }
                        else
                        {
                            _dictionary[key] = new DynamicItemFields(_engine, embeddedSchemaField.Value);
                        }
                    }
                    else
                    {
                        List <dynamic> embeddedFields = new List <dynamic>();

                        int i = 0;
                        foreach (ItemFields fields in embeddedSchemaField.Values)
                        {
                            var dif = new DynamicItemFields(_engine, fields);
                            dif.Index  = i++;
                            dif.IsLast = dif.Index == embeddedSchemaField.Values.Count - 1;
                            embeddedFields.Add(dif);
                        }
                        _dictionary[key] = embeddedFields;
                    }
                }
                else if (itemField is ComponentLinkField)
                {
                    ComponentLinkField componentLinkField = (ComponentLinkField)itemField;
                    if (componentLinkField.Definition.MaxOccurs == 1)
                    {
                        if (componentLinkField.Value == null)
                        {
                            _dictionary[key] = null;
                        }
                        else
                        {
                            _dictionary[key] = new ComponentModel(_engine, componentLinkField.Value);
                        }
                    }
                    else
                    {
                        List <ComponentModel> components = new List <ComponentModel>();
                        int i = 0;
                        foreach (Component c in componentLinkField.Values)
                        {
                            var cm = new ComponentModel(_engine, c);
                            cm.Index  = i++;
                            cm.IsLast = cm.Index == componentLinkField.Values.Count - 1;
                            components.Add(cm);
                        }
                        _dictionary[key] = components;
                    }
                }
                else if (itemField is ExternalLinkField)
                {
                    ExternalLinkField externalLink = (ExternalLinkField)itemField;
                    if (externalLink.Definition.MaxOccurs == 1)
                    {
                        _dictionary[key] = externalLink.Value;
                    }
                    else
                    {
                        _dictionary[key] = externalLink.Values;
                    }
                }
                else if (itemField is NumberField)
                {
                    NumberField numberField = (NumberField)itemField;
                    if (itemField.Definition.MaxOccurs == 1)
                    {
                        _dictionary[key] = numberField.Value;
                    }
                    else
                    {
                        _dictionary[key] = numberField.Values;
                    }
                }
                else
                {
                    _dictionary[key] = itemField.ToString();
                }
            }
        }