/// <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);
            }
        }
Пример #2
0
        private void SetOrUpdateMetadata(Component subject, EventArgs args, EventPhases phase)
        {
            // quick first test for ECL stub Component
            if (!subject.Title.StartsWith("ecl:") || subject.ComponentType != ComponentType.Multimedia) return;

            using (IEclSession eclSession = SessionFactory.CreateEclSession(subject.Session))
            {
                // determine if subject is an ECL stub Component from the list of available mountpoints
                IEclUri eclUri = eclSession.TryGetEclUriFromTcmUri(subject.Id);
                if (eclUri != null && MountPointIds.Contains(eclUri.MountPointId))
                {
                    // check if metadata field exists
                    ItemFields metadataFields = new ItemFields(subject.Metadata, subject.MetadataSchema);
                    if (metadataFields.Contains(_metadataXmlFieldName))
                    {
                        // only set value when update is true or metadata is not set
                        string metadata = ((SingleLineTextField)metadataFields[_metadataXmlFieldName]).Value;
                        if (_update || string.IsNullOrEmpty(metadata))
                        {
                            using (IContentLibraryContext context = eclSession.GetContentLibrary(eclUri))
                            {
                                // load actual ECL item so you can access its properties and metadata
                                IContentLibraryMultimediaItem eclItem = (IContentLibraryMultimediaItem) context.GetItem(eclUri);
                                try
                                {
                                    // implement your custom code here to set the metadata value
                                    // currently this reads the configured ECL metadata field and sets its value in the stub metadata
                                    if (!string.IsNullOrEmpty(eclItem.MetadataXml))
                                    {
                                        XNamespace ns = GetNamespace(eclItem.MetadataXml);
                                        XDocument eclMetadata = XDocument.Parse(eclItem.MetadataXml);

                                        XElement field = (from xml in eclMetadata.Descendants(ns + _metadataXmlFieldName) select xml).FirstOrDefault();
                                        if (field != null)
                                        {
                                            string value = field.Value;

                                            // only save value when metadata is empty or update is true and value differs
                                            if (string.IsNullOrEmpty(metadata) || (_update && !metadata.Equals(value)))
                                            {
                                                // update metadata
                                                if (_asynchronous)
                                                {
                                                    subject.CheckOut();
                                                }
                                                ((SingleLineTextField) metadataFields[_metadataXmlFieldName]).Value = value;
                                                subject.Metadata = metadataFields.ToXml();
                                                subject.Save();
                                                if (_asynchronous)
                                                {
                                                    subject.CheckIn();
                                                }

                                                Logger.Write(string.Format("added {0} to metadata of {1}", value, eclUri), "EclStubComponentEventHandlerExtension", LoggingCategory.General, TraceEventType.Information);
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Logger.Write(e, "EclStubComponentEventHandlerExtension", LoggingCategory.General);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #3
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);
            }
        }
Пример #4
0
        public static void OnPageCreate(Page page, LoadEventArgs args, EventPhases phases)
        {
            // only react on new Pages
            if (page.Id == TcmUri.UriNull)
            {
                StackTrace stackTrace = new StackTrace();
                foreach (var frame in stackTrace.GetFrames())
                {
                    // build Class.Method
                    MethodBase method = frame.GetMethod();
                    string     name   = method.ReflectedType.Name + "." + method.Name;

                    // only trigger on CoreServiceBase.GetDefaultData, not on CoreServiceBase.Create (which is the second call)
                    if (name.Equals("CoreServiceBase.GetDefaultData"))
                    {
                        break;
                    }
                    if (name.Equals("CoreServiceBase.Create"))
                    {
                        return;
                    }
                }

                const string metadataFieldName = "relatedContent";
                // bad example of hardcoding TCMURIs, but we at least use the context Publication
                string pageMetadataSchemaUri = string.Format("tcm:{0}-209-8", page.OrganizationalItem.Id.PublicationId);
                string seoSchemaUri          = string.Format("tcm:{0}-520-8", page.OrganizationalItem.Id.PublicationId);
                string seoFolderUri          = string.Format("tcm:{0}-1-2", page.OrganizationalItem.Id.PublicationId);

                if (page.MetadataSchema == null)
                {
                    // set Page metadata Schema
                    Schema meta = (Schema)page.Session.GetObject(pageMetadataSchemaUri);
                    page.MetadataSchema = meta;
                    page.Metadata       = meta.GetInstanceData(page.OrganizationalItem, LoadFlags.Expanded).Metadata;

                    Logger.Write(string.Format("Added metadata to Page {0} ({1})", page.Title, page.Id), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information);
                }

                // check if Component hasn't already been set
                ItemFields pageMeta = new ItemFields(page.Metadata, page.MetadataSchema);
                if (pageMeta.Contains(metadataFieldName))
                {
                    ComponentLinkField field = (ComponentLinkField)pageMeta[metadataFieldName];
                    if (field != null && field.Value == null)
                    {
                        // create a new SEO Component
                        Folder    folder    = (Folder)page.Session.GetObject(seoFolderUri);
                        Schema    seoSchema = (Schema)page.Session.GetObject(seoSchemaUri);
                        Component comp      = folder.GetNewObject <Component>();
                        comp.Title   = string.Format("Auto SEO Component {0}", Guid.NewGuid().ToString("N"));
                        comp.Schema  = seoSchema;
                        comp.Content = seoSchema.GetInstanceData(folder, LoadFlags.Expanded).Content;
                        comp.Save(true);
                        Logger.Write(string.Format("Created Component {0} ({1})", comp.Title, comp.Id), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information);

                        // set link in Page metadata
                        field.Value   = comp;
                        page.Metadata = pageMeta.ToXml();

                        Logger.Write(string.Format("Added Component Link to metadata of Page {0} ({1})", page.Title, page.Id), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information);
                    }
                }
            }
        }
Пример #5
0
        private void SetOrUpdateMetadata(Component subject, EventArgs args, EventPhases phase)
        {
            // quick first test for ECL stub Component
            if (!subject.Title.StartsWith("ecl:") || subject.ComponentType != ComponentType.Multimedia)
            {
                return;
            }

            using (IEclSession eclSession = SessionFactory.CreateEclSession(subject.Session))
            {
                // determine if subject is an ECL stub Component from the list of available mountpoints
                IEclUri eclUri = eclSession.TryGetEclUriFromTcmUri(subject.Id);
                if (eclUri != null && MountPointIds.Contains(eclUri.MountPointId))
                {
                    // check if metadata field exists
                    ItemFields metadataFields = new ItemFields(subject.Metadata, subject.MetadataSchema);
                    if (metadataFields.Contains(_metadataXmlFieldName))
                    {
                        // only set value when update is true or metadata is not set
                        string metadata = ((SingleLineTextField)metadataFields[_metadataXmlFieldName]).Value;
                        if (_update || string.IsNullOrEmpty(metadata))
                        {
                            using (IContentLibraryContext context = eclSession.GetContentLibrary(eclUri))
                            {
                                // load actual ECL item so you can access its properties and metadata
                                IContentLibraryMultimediaItem eclItem = (IContentLibraryMultimediaItem)context.GetItem(eclUri);
                                try
                                {
                                    // implement your custom code here to set the metadata value
                                    // currently this reads the configured ECL metadata field and sets its value in the stub metadata
                                    if (!string.IsNullOrEmpty(eclItem.MetadataXml))
                                    {
                                        XNamespace ns          = GetNamespace(eclItem.MetadataXml);
                                        XDocument  eclMetadata = XDocument.Parse(eclItem.MetadataXml);

                                        XElement field = (from xml in eclMetadata.Descendants(ns + _metadataXmlFieldName) select xml).FirstOrDefault();
                                        if (field != null)
                                        {
                                            string value = field.Value;

                                            // only save value when metadata is empty or update is true and value differs
                                            if (string.IsNullOrEmpty(metadata) || (_update && !metadata.Equals(value)))
                                            {
                                                // update metadata
                                                if (_asynchronous)
                                                {
                                                    subject.CheckOut();
                                                }
                                                ((SingleLineTextField)metadataFields[_metadataXmlFieldName]).Value = value;
                                                subject.Metadata = metadataFields.ToXml();
                                                subject.Save();
                                                if (_asynchronous)
                                                {
                                                    subject.CheckIn();
                                                }

                                                Logger.Write(string.Format("added {0} to metadata of {1}", value, eclUri), "EclStubComponentEventHandlerExtension", LoggingCategory.General, TraceEventType.Information);
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Logger.Write(e, "EclStubComponentEventHandlerExtension", LoggingCategory.General);
                                }
                            }
                        }
                    }
                }
            }
        }