/// <summary> /// On Page Save. /// </summary> /// <param name="page"></param> /// <param name="args"></param> /// <param name="phase"></param> public static void OnPageSave(Page page, SaveEventArgs args, EventPhases phase) { if (IsContainerPage(page)) { try { IList <Container> containers = Container.GetContainers(page); if (containers.Count > 0) { var foundComponentInWrongContainer = ProcessComponentPresentationsInWrongContainer(page, containers); if (!foundComponentInWrongContainer) { var containerMetadata = ContainerMetadata.Load(page); if (containerMetadata != null && containerMetadata.Count != containers.Count) { ProcessContainersOnWrongLocation(containers, page, containerMetadata); } } ProcessComponentTemplates(page.ComponentPresentations); ContainerMetadata.Save(page, containers); } } catch (Exception e) { Log.Error("Error when processing container page: " + e); } } }
public EventRegistration(UserControl target, string type, ScriptFunction listener, EventPhases applyToPhase) { _target = target; _type = type; _listener = listener; _applyToPhase = applyToPhase; }
private static void OnTemplateBuildingBlockSave(TemplateBuildingBlock subject, SaveEventArgs e, EventPhases phase) { if (!subject.IsAssemblyTemplateBuildingBlock()) return; using (var session = subject.Session) { var templatingAssembly = new TemplatingAssembly(subject); foreach (var embeddedParameterSchema in templatingAssembly.EmbeddedParameterSchemas) { if (session.IsExistingObject(String.Concat(subject.OrganizationalItem.WebDavUrl, "/", embeddedParameterSchema.Title, ".xsd"))) continue; var parameterSchema = new Schema(session, subject.OrganizationalItem.Id) { Title = embeddedParameterSchema.Title, Description = embeddedParameterSchema.Title, Purpose = SchemaPurpose.TemplateParameters, RootElementName = "Parameters", Xsd = embeddedParameterSchema.Xsd }; parameterSchema.Save(true); } foreach (var cSharpTemplateBuildingBlock in templatingAssembly.CSharpTemplateBuildingBlocks) { //If a TBB already exists if (session.IsExistingObject(String.Concat(subject.OrganizationalItem.WebDavUrl, "/", cSharpTemplateBuildingBlock.Title, ".tbbcs"))) continue; //Create a new C# TBB var templateBuildingBlock = new TemplateBuildingBlock(session, subject.OrganizationalItem.Id) { Title = cSharpTemplateBuildingBlock.Title, TemplateType = TemplateTypes.CSharpTemplate, Content = String.Format(CSharpTemplateBuildingBlockContent, templatingAssembly.Id, cSharpTemplateBuildingBlock.ClassName) }; if (cSharpTemplateBuildingBlock.ParameterSchema != null) { if (cSharpTemplateBuildingBlock.ParameterSchema.ToLower().StartsWith("/webdav/") || cSharpTemplateBuildingBlock.ParameterSchema.ToLower().StartsWith("tcm:")) { var parameterSchema = (Schema) session.GetObject(cSharpTemplateBuildingBlock.ParameterSchema); templateBuildingBlock.ParameterSchema = parameterSchema; } else if (cSharpTemplateBuildingBlock.ParameterSchema.ToLower().StartsWith("resource:")) { var parameterSchemaUrl = String.Concat(subject.OrganizationalItem.WebDavUrl, "/", Regex.Match(cSharpTemplateBuildingBlock.ParameterSchema, @"[\w ]*(?=\.xsd$)").Value, ".xsd"); var parameterSchema = (Schema)session.GetObject(parameterSchemaUrl); templateBuildingBlock.ParameterSchema = parameterSchema; } } templateBuildingBlock.Save(true); } } }
/// <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); } }
/// <summary> /// On publish of a page, post that the page has been been in slack. /// </summary> private void OnPublish(Page page, SetPublishStateEventArgs e, EventPhases phase) { SlackClient client = new SlackClient(SLACK_WEBHOOK_URL); string status = e.IsPublished ? "published" : "unpublished"; client.PostMessage(text: "Page '" + page.Title + "' was " + status + " to " + e.Target.Title + " at " + DateTime.Now); }
private void OnComponentCheckIn(Component component, CheckInEventArgs args, EventPhases phase) { configManager = ConfigurationManager.GetInstance(component); string value = configManager["Publication"]; Dictionary <string, string> configs = configManager.Configurations; string value2 = configs["Publication"]; }
private void OnComponentCheckIn(Component component, CheckInEventArgs args, EventPhases phase) { configManager = ConfigurationManager.GetInstance(component); string value = configManager["Publication"]; Dictionary<string, string> configs = configManager.Configurations; string value2 = configs["Publication"]; }
private void EventHandler(IdentifiableObject subject, EventArgs eventArgs, EventPhases phase) { var record = new Record(); //Set Environment record.Environment = new CMEnvironment { Name = ConfigurationManager.AppSettings.Get("NF4T_CMEnvironmentKey") }; //Set Subject record.Subject = new Subject { TcmId = subject.Id, Title = subject.Title, Type = subject.GetType(), CreationDate = subject.CreationDate, LastModifiedDate = subject.RevisionDate }; //Extract ItemTypeSpecifics if (subject is Component) { var component = subject as Component; record.Subject.SchemaTcmId = component.Schema.Id.ToString(); } //Set Event record.Event = new Event { Type = eventArgs.GetType(), TimeStamp = DateTime.Now }; //Extract ItemTypeSpecifics if (eventArgs is SaveEventArgs) { var saveEventArgs = eventArgs as SaveEventArgs; record.Event.IsNewItem = saveEventArgs.IsNewItem; } //Extract EventType Specifics switch (eventArgs.GetType().Name) { case "SaveEventArgs": break; default: break; } var events = eventArgs as SaveEventArgs; }
private void ComponentSaveInitiatedHandler(Component component, SaveEventArgs args, EventPhases phase) { string[] interestingMimeTypes = new string[] { "image/jpeg", "image/gif", "image/png", "image/x-bmp" }; if (interestingMimeTypes.Contains(component.BinaryContent.MultimediaType.MimeType)) { string title = component.Schema.Title; Regex re = new Regex(@" \[\s* # first '[' and some whitespace (?<width>\d*) # um.. the width \s*x\s* # the 'x' (?<height>\d*) # height \s*\] # finish off with another squaredy-bracket ", RegexOptions.IgnorePatternWhitespace); Match match = re.Match(title); if (!match.Success) { return; } int expectedWidth = int.Parse(match.Groups["width"].Value); int expectedHeight = int.Parse(match.Groups["height"].Value); if (component.BinaryContent != null) { using (MemoryStream mem = new MemoryStream()) { component.BinaryContent.WriteToStream(mem); Bitmap bitmap = null; try { bitmap = new Bitmap(mem); if (expectedWidth != bitmap.Width || expectedHeight != bitmap.Height) { throw new WrongSizeImageException(string.Format("You can only save a MM component of type {0} if it is {1}x{2}px. This image is {3}x{4}px" , title, expectedWidth, expectedHeight, bitmap.Width, bitmap.Height)); } } catch (System.ArgumentException) { if (mem.Length > 1) { throw new WrongSizeImageException("Unable to process this image, probably because it is too large, or not in a recognised image format."); } else throw; } finally { if (bitmap != null) { bitmap.Dispose(); } } } } } }
private void PublishTransactionSaveAction(PublishTransaction subject, SaveEventArgs args, EventPhases phases) { // ignore items in website structure publication (they are always empty because of the child publications only resolver) if (subject.PublishContexts[0].Publication.Id.ItemId == _websiteStructurePublicationUri.ItemId) { return; } // after the publisher has used the Resolve Engine to figure out what to publish/render or unpublish, // it reflects the resolved results in PublishTransaction.PublishContexts[0].ProcessedItems // currently there will always be exactly one PublishContext per PublishTransaction if (subject.PublishContexts[0].ProcessedItems.Count == 0 && subject.State.Equals(PublishTransactionState.Success)) { // change state to warning and inform that this publish transaction had 0 items // could change state by setting property PublishTransaction.State, // but the property PublishTransaction.Information is readonly, so let's use IdentifiableObject.Update XmlDocument delta = new XmlDocument(); delta.LoadXml(string.Format(DeltaXml, Constants.TcmR6Namespace, subject.Id, Message, PublishTransactionState.Warning)); subject.Update(delta.DocumentElement); } }
private static void OnItemSavePre(VersionedItem item, SaveEventArgs args, EventPhases phase) { var title = item.Title; var writer = new FileWriter(); //var repo = new UserActionRepository(new SnitchDb()); //var UserRepo = new UserRepository(new SnitchDb()); var action = new UserAction() { Status = item.Revision.ToString(), ActionDetails = item.WebDavUrl, ActionName = item.Title, ActionTime = item.RevisionDate }; var item4 = args; var check = ""; var user = new User() { Name = item.Session.User.Title, UserName = item.Session.User.Id, UserActions = new List <UserAction>() { new UserAction() { ActionDetails = item.WebDavUrl, ActionName = item.Title, ActionTime = DateTime.Now } } }; //repo.Add(action); //UserRepo.Add(user); Logger.Write("[OnItemSavePre];", "could not work", LoggingCategory.General); writer.WriteAction(user); args.ContextVariables.Add(title, DateTime.Now); }
/// <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 ComponentLoadAction(Component subject, LoadEventArgs args, EventPhases phases) { try { // the TCMURI of the Publication from this item TcmUri contextRepository = subject.ContextRepository.Id; // the TCMURI of the Publication where this item was localized TcmUri owningRepository = subject.OwningRepository.Id; Logger.Write(string.Format("Component: {0}, Context: {1}, Owning: {2}", subject.Id, contextRepository, owningRepository), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information); if (subject.IsLocalized) { BluePrintChainFilter filter = new BluePrintChainFilter(subject.Session) { Direction = BluePrintChainDirection.Up }; // the TCMURI of the Publication where this item was created owningRepository = new TcmUri(subject.GetBluePrintChain(filter).Last().Id.ContextRepositoryId, ItemType.Publication); } // build TcmUri of parent Component // (note using ItemId of owningRepositiory as a PublicationId, // since that is a Publication TcmUri) TcmUri uri = new TcmUri(subject.Id.ItemId, subject.Id.ItemType, owningRepository.ItemId); // load parent Component Component parent = new Component(uri, subject.Session); Logger.Write(string.Format("Component: {0}, Context: {1}, Owning: {2}, Parent: {3}", subject.Id, contextRepository, owningRepository, parent.Id), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information); Component check = GetParentComponent(subject); Logger.Write(string.Format("GetParentComponent: {0}", check.Id), "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Information); } catch (Exception e) { Logger.Write(e, "ExampleEventHandlerExtension", LoggingCategory.General, TraceEventType.Error); } }
private static void ComponentTemplateCreate(ComponentTemplate ct, LoadEventArgs args, EventPhases phase) { if (ct.Version != 0) { return; } // add your TBBs here }
/// <summary> /// Audits updates to versionless items /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="SaveEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditVersionless(IdentifiableObject identifiableObject, SaveEventArgs args, EventPhases phase) { if (phase == EventPhases.Initiated) { try { // Load the original unmodified item XML from the database IdentifiableObject oldIdentifiableObject = identifiableObject.Session.GetObject(identifiableObject.Id); XElement original = XElement.Parse(oldIdentifiableObject.ToXml().OuterXml); XElement updated = XElement.Parse(identifiableObject.ToXml().OuterXml); XElement difference = XMLDelta.Compare(original, updated); if (difference != null) AuditContentEdit("Update", identifiableObject, identifiableObject.GetType().Name, new SqlXml(difference.CreateReader())); else AuditContentEdit("Update", identifiableObject, identifiableObject.GetType().Name, null); } catch (Exception ex) { Logger.Write(ex, "TcmEvents.Audit", LoggingCategory.General, TraceEventType.Error); } } }
private static void OnComponentSavePre(Component comp, SaveEventArgs args, EventPhases phase) { //Do Something... }
/// <summary> /// Audits the object unlocalizations /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="UnLocalizeEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditUnLocalize(RepositoryLocalObject repositoryObject, UnLocalizeEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) AuditContentEdit("UnLocalize", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); }
/// <summary> /// Audits object version rollbacks. /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="RollbackEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditRollback(RepositoryLocalObject repositoryObject, RollbackEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) AuditContentEdit("Rollback", repositoryObject, String.Format("Delete Versions: {0}", args.DeleteVersions), new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); }
/// <summary> /// Audits the purging of old versions /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="PurgeOldVersionsEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditPurgeOldVersions(RepositoryLocalObject repositoryObject, PurgeOldVersionsEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) AuditContentEdit("PurgeVersions", repositoryObject, null, null); }
/// <summary> /// Audits a publishing transaction /// </summary> /// <param name="transaction"><see cref="T:Tridion.ContentManager.Publishing.PublishTransaction" /></param> /// <param name="args">The <see cref="SaveEventArgs"/> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditPublish(PublishTransaction transaction, SaveEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted && transaction.State == PublishTransactionState.Success) { try { using (SqlConnection connection = Connection) { // Register the publish transaction using (SqlCommand sqlAuditPublishTransaction = new SqlCommand() { CommandText = "AuditPublishTransaction", CommandType = CommandType.StoredProcedure, Connection = connection }) { sqlAuditPublishTransaction.AddParameter("@Transaction", SqlDbType.VarChar, transaction.Id.ToString()); sqlAuditPublishTransaction.AddParameter("@Action", SqlDbType.VarChar, (transaction.Instruction is PublishInstruction ? "Publish" : "Unpublish")); sqlAuditPublishTransaction.AddParameter("@TimeStamp", SqlDbType.DateTime, transaction.StateChangeDateTime); sqlAuditPublishTransaction.AddParameter("@Username", SqlDbType.VarChar, transaction.Creator.Title.ToUpper()); sqlAuditPublishTransaction.AddParameter("@UserDescription", SqlDbType.NVarChar, transaction.Creator.Description); int transactionId = Convert.ToInt32(sqlAuditPublishTransaction.ExecuteScalar()); if (transactionId > 0) { using (SqlCommand sqlAuditPublishedItem = new SqlCommand() { CommandText = "AuditPublishedItem", CommandType = CommandType.StoredProcedure, Connection = connection }) { // Register the publication transaction sqlAuditPublishedItem.AddParameter("@TransactionID", SqlDbType.Int, transactionId); sqlAuditPublishedItem.AddParameter("@PublicationTarget", SqlDbType.VarChar); sqlAuditPublishedItem.AddParameter("@Publication", SqlDbType.VarChar); sqlAuditPublishedItem.AddParameter("@ItemID", SqlDbType.VarChar); sqlAuditPublishedItem.AddParameter("@ItemTitle", SqlDbType.NVarChar); sqlAuditPublishedItem.AddParameter("@ItemTemplate", SqlDbType.VarChar); sqlAuditPublishedItem.AddParameter("@IsComponentTemplate", SqlDbType.Bit); sqlAuditPublishedItem.AddParameter("@IsDCP", SqlDbType.Bit); foreach (PublishContext publishContext in transaction.PublishContexts) { foreach (ProcessedItem processedItem in publishContext.ProcessedItems) { // Register each published item ResolvedItem resolvedItem = processedItem.ResolvedItem; sqlAuditPublishedItem.SetValue("@PublicationTarget", publishContext.PublicationTarget.Id.ToString()); sqlAuditPublishedItem.SetValue("@Publication", publishContext.Publication.Id.ToString()); sqlAuditPublishedItem.SetValue("@ItemID", resolvedItem.Item.VersionedItemId()); sqlAuditPublishedItem.SetValue("@ItemTitle", resolvedItem.Item.Title); sqlAuditPublishedItem.SetValue("@ItemTemplate", resolvedItem.Template.VersionedItemId()); sqlAuditPublishedItem.SetValue("@IsComponentTemplate", resolvedItem.IsComponentPresentation); sqlAuditPublishedItem.SetValue("@IsDCP", resolvedItem.IsDynamicComponentPresentation); sqlAuditPublishedItem.ExecuteNonQuery(); } } } } } } } catch (Exception ex) { Logger.Write(ex, "TcmEvents.Audit", LoggingCategory.General, TraceEventType.Error); } } }
public void SendPublishInfo(PublishTransaction publishTransaction, SaveEventArgs args, EventPhases phase) { //Get Tcm Uri of publisher user and published Url of page and send info to WebService if (publishTransaction.State == PublishTransactionState.Success) { var page = publishTransaction.Items.First() as Page; var publishedInfo = new { TCMUri = publishTransaction.Creator.Id, URL = page.GetPublishUrl(publishTransaction.TargetType).ToString() }; string json = JsonConvert.SerializeObject(publishedInfo, Formatting.Indented); SendJson(json); } }
/// <summary> /// Audits updates to versionless items /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="SaveEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditVersionless(IdentifiableObject identifiableObject, SaveEventArgs args, EventPhases phase) { if (phase == EventPhases.Initiated) { try { // Load the original unmodified item XML from the database IdentifiableObject oldIdentifiableObject = identifiableObject.Session.GetObject(identifiableObject.Id); XElement original = XElement.Parse(oldIdentifiableObject.ToXml().OuterXml); XElement updated = XElement.Parse(identifiableObject.ToXml().OuterXml); XElement difference = XMLDelta.Compare(original, updated); if (difference != null) { AuditContentEdit("Update", identifiableObject, identifiableObject.GetType().Name, new SqlXml(difference.CreateReader())); } else { AuditContentEdit("Update", identifiableObject, identifiableObject.GetType().Name, null); } } catch (Exception ex) { Logger.Write(ex, "TcmEvents.Audit", LoggingCategory.General, TraceEventType.Error); } } }
/// <summary> /// Publish Event handler which is triggered on publishing (or unpublishing) any repository local object. The handler /// will publish the item if published in a source publication to any publications defined as target publications. /// </summary> /// <param name="publishedItem">Item being published (page, component, category etc)</param> /// <param name="args">Publishing or unpublishing arguments</param> /// <param name="phase">event phase for the transaction</param> private void PublishEvent(RepositoryLocalObject publishedItem, PublishOrUnPublishEventArgs args, EventPhases phase) { var publication = publishedItem.ContextRepository as Publication; // Make sure the publication is in the list of publications where publishing should be mirrored if (Settings.SOURCE_PUBS.Any(p => p.Equals(publication?.Title) || p.Equals(publication?.Id))) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("Publication title is in the list of source publications."); var publishStatus = args is PublishEventArgs ? "Publish" : "Unpublish"; var publishEvent = args is PublishEventArgs ? args as PublishEventArgs : null; var unpublishEvent = args is UnPublishEventArgs ? args as UnPublishEventArgs : null; var creator = publishEvent != null? publishEvent.PublishTransactions?.FirstOrDefault()?.Creator: unpublishEvent?.PublishTransactions?.FirstOrDefault()?.Creator; logger.Info( $"{publishStatus} event " + $"[initiated by]: {creator.Title} ({creator.Id}) -- " + $"[publishing targets]: {args.Targets.Select(t => $"{t.Title} ({t.Id})")?.PrintList()} -- " + $"[original publish item]: {publishedItem.Id} ({publishedItem.Title}) -- " + $"[all {publishStatus} items (also published)]: {args.Items.Select(i => $"{i.Title} ({i.Id})")?.PrintList()}." ); } // Get the instruction & figure out if its a publish or an unpublish var publishUnpublishInstruction = TridionUtil.GetPublishOrUnpublishInstruction(args); // Get the publications for which publishing should be mirrored var mirrorPublications = TridionUtil.GetPublications(Settings.TARGET_PUBS, publishedItem.Session); if (mirrorPublications == null || mirrorPublications.Count < 1) { logger.Debug("No mirror publications found."); return; } if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug($"Found the list of mirror publications : {mirrorPublications.Select(p => p.Title + ", ")?.PrintList()} ."); } // Get the item which needs to be published in the mirrored publication var mirrorItems = TridionUtil.GetItemsInPublications(publishedItem, mirrorPublications?.Select(p => p.Id)?.ToList(), publishedItem.Session); if (mirrorItems == null || mirrorItems.Count < 1) { logger.Debug("No mirror items found."); return; } if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug($"Mirroring {mirrorItems.Count} publish items : {mirrorItems.Select(i => i.Id + ", ")?.PrintList()}."); } try { // Publish the items to be mirrored in the mirrored publications if (args.Targets.Count() > 0 && mirrorItems.Count() > 0 && mirrorPublications.Count() > 0) { var publishedItemIds = mirrorItems.Select(p => p.Id.ToString())?.PrintList(); var publicationTitles = mirrorPublications.Select(p => p.Title)?.PrintList(); var publishingTargetIds = args.Targets.Select(t => t.Id.ToString())?.PrintList(); var targetTypes = args.Targets.Select(t => t as TargetType); if (targetTypes == null || targetTypes.Count() < 1) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("No target types found. Returning."); } return; } if (args is PublishEventArgs) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("Publishing event being mirrored."); } var publishInstruction = (PublishInstruction)publishUnpublishInstruction; if (Settings.FORCE_PUBLISH_CHILD_PUBS) { publishInstruction.ResolveInstruction.IncludeChildPublications = true; } if (Settings.FORCE_PUBLISH_MINOR_VERSION) { publishInstruction.ResolveInstruction.IncludeDynamicVersion = true; } if (Settings.FORCE_PUBLISH_WORKFLOW_VERSION) { publishInstruction.ResolveInstruction.IncludeWorkflow = true; } // if the setting is selected to mirror the transaction only if publish to children is selected, but the setting is false, exit. if (Settings.MIRROR_IF_PROPOGATE_SELECTED && !publishInstruction.ResolveInstruction.IncludeChildPublications) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("Exiting as mirror if propogate selected, but setting is false."); } return; } if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Info($"Mirroring publishing items '{publishedItemIds}' -- to publications {publicationTitles} -- to targets {targetTypes.Select(t => t.Title)?.PrintList()}."); } PublishEngine.Publish(mirrorItems, publishInstruction, targetTypes, PublishPriority.Low); } else if (args is UnPublishEventArgs) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("Unpublishing event being mirrored."); } var unpublishInstruction = (UnPublishInstruction)publishUnpublishInstruction; if (Settings.FORCE_PUBLISH_CHILD_PUBS) { unpublishInstruction.ResolveInstruction.IncludeChildPublications = true; } // if the setting is selected to mirror the transaction only if publish to children is selected, but the setting is false, exit. if (Settings.MIRROR_IF_PROPOGATE_SELECTED && !unpublishInstruction.ResolveInstruction.IncludeChildPublications) { if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Debug("Exiting as mirror if propogate selected, but setting is false."); } return; } if (Settings.PUBLISH_LOGGING_ENABLED) { logger.Info($"Mirroring unpublishing items '{publishedItemIds}' -- to publications {publicationTitles} -- to targets {publishingTargetIds}."); } PublishEngine.UnPublish(mirrorItems, unpublishInstruction, targetTypes, PublishPriority.Low); } } } catch (Exception ex) { logger.Error($"Error publishing items : {ex.Message} {ex.ToString()} {ex.StackTrace}"); } } }
private void Handler(RepositoryLocalObject item, SaveEventArgs args, EventPhases phase) { // perform custom action when saving // in our case adding the suffix to the item title item.Title = $"{item.Title}_SampleExtensionSuffix"; }
/// <summary> /// On (Save, and) Check-in of a Component, create a Page for that Component and update an index Page with the Component and publish both to a staging target. /// </summary> /// <remarks> /// The metadata of the Folder the Component resides in, will be used as the configuration for the actions. /// </remarks> /// <param name="subject">checked in Component</param> /// <param name="args">check in event arguments</param> /// <param name="phase">event phase</param> private static void ComponentCheckInAction(Component subject, CheckInEventArgs args, EventPhases phase) { // get Folder from Component for configuration metadata Folder folder = (Folder)subject.OrganizationalItem; // proceed when Folder has metadata if (folder.Metadata == null) { return; } ItemFields metadata = new ItemFields(folder.Metadata, folder.MetadataSchema); ReiConfig config = new ReiConfig(metadata); // proceed when metadata contains valid URIs, and Schema of Component is recognised if (!config.IsValid || subject.Schema.Id.ItemId != config.SchemaUri.ItemId) { return; } // create list of items to publish List <IdentifiableObject> items = new List <IdentifiableObject>(); // if Component is already used on any Page then no need to create new Page and update index, just publish Component UsingItemsFilter pageFilter = new UsingItemsFilter(subject.Session) { ItemTypes = new List <ItemType> { ItemType.Page } }; if (subject.HasUsingItems(pageFilter)) { items.Add(subject); } else { // create Page and add Component Presentation (using Context Publication of Structure Group) TcmUri localUri = ReiConfig.TransformTcmUri(subject.Id, config.StructureGroupUri); Component localComponent = new Component(localUri, subject.Session); ComponentTemplate componentTemplate = new ComponentTemplate(config.ComponentTemplateUri, subject.Session); Page page = new Page(subject.Session, config.StructureGroupUri); try { page.Title = subject.Title; page.FileName = GetSafeFileName(subject.Title); page.PageTemplate = new PageTemplate(config.PageTemplateUri, subject.Session); page.ComponentPresentations.Add(new ComponentPresentation(localComponent, componentTemplate)); page.Save(true); // add Page to publish items list items.Add(page); } catch (Exception ex) { Logger.Write(ex, ReiConfig.Name, LoggingCategory.General, TraceEventType.Error); } // add Component to index Page (using Context Publication of index Page) localUri = ReiConfig.TransformTcmUri(subject.Id, config.IndexPageUri); localComponent = new Component(localUri, subject.Session); componentTemplate = new ComponentTemplate(config.IndexComponentTemplateUri, subject.Session); Page indexPage = new Page(config.IndexPageUri, subject.Session); try { indexPage.CheckOut(); indexPage.ComponentPresentations.Add(new ComponentPresentation(localComponent, componentTemplate)); indexPage.Save(true); // add index Page to publish items list items.Add(indexPage); } catch (Exception ex) { Logger.Write(ex, ReiConfig.Name, LoggingCategory.General, TraceEventType.Error); } } // publish items if (items.Count > 0) { List <TargetType> targets = new List <TargetType> { new TargetType(config.TargetTypeUri, subject.Session) }; PublishInstruction publishInstruction = new PublishInstruction(subject.Session); PublishEngine.Publish(items, publishInstruction, targets, ReiConfig.Priority); } else { Logger.Write("No items were published.", ReiConfig.Name, LoggingCategory.General, TraceEventType.Information); } }
private static void SendNotification(PublishTransaction subject, SaveEventArgs e, EventPhases phases) { // only send a message when the publishing is finished. The publish transaction gets saved at least when created and on a status update if (!subject.IsCompleted) { return; } // create an object that contains some data that we want to send to the client as the details of the message JObject details = JObject.FromObject(new { creatorId = subject.Creator.Id.ToString(), state = subject.State.ToString(), title = subject.Title }); NotificationMessage message = new NotificationMessage { // we need an identifier that we can use in the UI extension to distinguish our messages from others Action = "example:publishtransactionfinished", SubjectIds = new[] { subject.Id.ToString() }, Details = details.ToString() }; subject.Session.NotificationsManager.BroadcastNotification(message); }
private static void PagePublishOrUnpublishAction(Page page, PublishOrUnPublishEventArgs args, EventPhases phase) { if (page.Title.ToLower().Contains("do not publish")) { throw new PublisherException(new LocalizableMessage(Properties.Resources.ResourceManager, "DoNotPublishError", new object[] { page })); } }
private void OnTBBSavePre(TemplateBuildingBlock tbb, CheckInEventArgs args, EventPhases phase) { configManager = ConfigurationManager.GetInstance(tbb); }
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 ComponentSaveInitiatedHandler(Component component, SaveEventArgs args, EventPhases phase) { ValidateMultimediaFilesize(component); }
// TODO: Consider some priority system between regions to get the best match instead of first match // TODO: Handle delete component case here??? // TODO: Verify that all added components are put on the correct place. If it is added after a component that is used several times it is added to the first region the component is located // TODO: Consider to rebuild the page component presentation list from scratch based by iterating through the regions public static void OnPageSave(Page page, SaveEventArgs args, EventPhases phase) { Logger.Write("On Page Save", "RegionGravityHandler", LogCategory.Custom, System.Diagnostics.TraceEventType.Information); if ( IsRegionPage(page) ) { IList<Region> regions = Region.GetRegions(page); Logger.Write("Regions: " + regions.Count, "RegionGravityHandler", LogCategory.Custom, System.Diagnostics.TraceEventType.Information); if (regions.Count > 0) { // Check if last component really belongs to the last region, if not let some region gravity happen on it // This is primarily to support adding components on-the-fly in regions via XPM // Region lastRegion = regions[regions.Count - 1]; bool foundNewComponent = false; if (lastRegion.ComponentPresentations.Count > 0) { ComponentPresentationInfo lastCP = lastRegion.ComponentPresentations[lastRegion.ComponentPresentations.Count - 1]; if (lastCP.RegionIndex != -1 ) { Region region = GetRegionByIndex(regions, lastCP.RegionIndex); Logger.Write("Found region: " + region.Name, "RegionGravityHandler", LogCategory.Custom, System.Diagnostics.TraceEventType.Information); if (region != null) { region.Add(lastCP.ComponentPresentation); // Remove the last entry from the page, because now the CP is added to another region on the page // page.ComponentPresentations.RemoveAt(page.ComponentPresentations.Count - 1); foundNewComponent = true; } } } if (!foundNewComponent) { Logger.Write("No new component added to the bottom...", "RegionGravityHandler", LogCategory.Custom, System.Diagnostics.TraceEventType.Information); //ProcessComponentPresentationsInWrongRegion(page.ComponentPresentations, regions); } ProcessComponentTemplates(page.ComponentPresentations); /* if ( false ) // OLD CODE!!! { // Check if last component really belongs to the last region, if not let some region gravity happen on it // This is primarily to support adding components on-the-fly in regions via XPM // Region lastRegion = regions[regions.Count - 1]; if (lastRegion.ComponentPresentations.Count > 0) { ComponentPresentationInfo lastCP = lastRegion.ComponentPresentations[lastRegion.ComponentPresentations.Count - 1]; if (lastRegion.CanContain(lastCP.ComponentPresentation) == false) { Region region = GetMatchingRegion(regions, lastCP.ComponentPresentation); if (region != null) { region.Add(lastCP.ComponentPresentation); // Remove the last entry from the page, because now the CP is added to another region on the page // page.ComponentPresentations.RemoveAt(page.ComponentPresentations.Count - 1); } } } } * */ } } }
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> /// Audits object version rollbacks. /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="RollbackEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditRollback(RepositoryLocalObject repositoryObject, RollbackEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) { AuditContentEdit("Rollback", repositoryObject, String.Format("Delete Versions: {0}", args.DeleteVersions), new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); } }
/// <summary> /// Audits the object unlocalizations /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="UnLocalizeEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditUnLocalize(RepositoryLocalObject repositoryObject, UnLocalizeEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) { AuditContentEdit("UnLocalize", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); } }
/// <summary> /// Audits object or version deletions /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="DeleteEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditDelete(RepositoryLocalObject repositoryObject, DeleteEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) // Discern between deleting objects and deleting object versions if (repositoryObject.Id.IsVersionless) AuditContentEdit("Delete", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); else AuditContentEdit("DeleteVersion", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); }
/// <summary> /// Audits object or version deletions /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="DeleteEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditDelete(RepositoryLocalObject repositoryObject, DeleteEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) { // Discern between deleting objects and deleting object versions if (repositoryObject.Id.IsVersionless) { AuditContentEdit("Delete", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); } else { AuditContentEdit("DeleteVersion", repositoryObject, null, new SqlXml(repositoryObject.ToXml().CreateNavigator().ReadSubtree())); } } }
/// <summary> /// Audits the purging of old versions /// </summary> /// <param name="repositoryObject"><see cref="T:Tridion.ContentManager.ContentManagement.RepositoryLocalObject" /></param> /// <param name="args">The <see cref="PurgeOldVersionsEventArgs" /> instance containing the event data.</param> /// <param name="phase"><see cref="T:Tridion.ContentManager.Extensibility.EventPhases" /></param> private void AuditPurgeOldVersions(RepositoryLocalObject repositoryObject, PurgeOldVersionsEventArgs args, EventPhases phase) { if (phase == EventPhases.TransactionCommitted) { AuditContentEdit("PurgeVersions", repositoryObject, null, null); } }
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); } } } } } } }
private void ComponentSaveInitiatedHandler(Component component, SaveEventArgs args, EventPhases phase) { string[] interestingMimeTypes = new string[] { "image/jpeg", "image/gif", "image/png", "image/x-bmp" }; if (interestingMimeTypes.Contains(component.BinaryContent.MultimediaType.MimeType)) { string title = component.Schema.Title; Regex re = new Regex(@" \[\s* # first '[' and some whitespace (?<width>\d*) # um.. the width \s*x\s* # the 'x' (?<height>\d*) # height \s*\] # finish off with another squaredy-bracket ", RegexOptions.IgnorePatternWhitespace); Match match = re.Match(title); if (!match.Success) { return; } int expectedWidth = int.Parse(match.Groups["width"].Value); int expectedHeight = int.Parse(match.Groups["height"].Value); if (component.BinaryContent != null) { using (MemoryStream mem = new MemoryStream()) { component.BinaryContent.WriteToStream(mem); Bitmap bitmap = null; try { bitmap = new Bitmap(mem); if (expectedWidth != bitmap.Width || expectedHeight != bitmap.Height) { throw new WrongSizeImageException(string.Format("You can only save a MM component of type {0} if it is {1}x{2}px. This image is {3}x{4}px" , title, expectedWidth, expectedHeight, bitmap.Width, bitmap.Height)); } } catch (System.ArgumentException) { if (mem.Length > 1) { throw new WrongSizeImageException("Unable to process this image, probably because it is too large, or not in a recognised image format."); } else { throw; } } finally { if (bitmap != null) { bitmap.Dispose(); } } } } } }