/// <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); } }
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); } } } } } } }
/// <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); } }
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); } } } }
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); } } } } } } }