private IContentLibraryMultimediaItem GetEclItem(string eclStubComponentId, out IContentLibraryContext eclContext) { _log.Debug("Retrieving ECL item for ECL Stub Component: " + eclStubComponentId); IEclUri eclUri = _eclSession.TryGetEclUriFromTcmUri(eclStubComponentId); if (eclUri == null) { throw new Exception("Unable to get ECL URI for ECL Stub Component: " + eclStubComponentId); } eclContext = _eclSession.GetContentLibrary(eclUri); // This is done this way to not have an exception thrown through GetItem, as stated in the ECL API doc. // The reason to do this, is because if there is an exception, the ServiceChannel is going into the aborted state. // GetItems allows up to 20 (depending on config) connections. IList <IContentLibraryItem> eclItems = eclContext.GetItems(new[] { eclUri }); IContentLibraryMultimediaItem eclItem = (eclItems == null) ? null : eclItems.OfType <IContentLibraryMultimediaItem>().FirstOrDefault(); if (eclItem == null) { eclContext.Dispose(); throw new Exception(string.Format("ECL item '{0}' not found (TCM URI: '{1}')", eclUri, eclStubComponentId)); } _log.Debug(string.Format("Retrieved ECL item for ECL Stub Component '{0}': {1}", eclStubComponentId, eclUri)); return(eclItem); }
internal void ProcessEclStubComponent(Component eclStubComponent) { IContentLibraryContext eclContext; IContentLibraryMultimediaItem eclItem = GetEclItem(eclStubComponent.Id, out eclContext); // This may look a bit unusual, but we have to ensure that ECL Item members are accessed *before* the ECL Context is disposed. using (eclContext) { eclStubComponent.EclId = eclItem.Id.ToString(); string directLinkToPublished = eclItem.GetDirectLinkToPublished(null); eclStubComponent.Multimedia.Url = string.IsNullOrEmpty(directLinkToPublished) ? PublishBinaryContent(eclItem, eclStubComponent.Id) : directLinkToPublished; // Set additional ECL Item properties as ExtensionData on the ECL Stub Component. const string eclSectionName = "ECL"; eclStubComponent.AddExtensionProperty(eclSectionName, "DisplayTypeId", eclItem.DisplayTypeId); eclStubComponent.AddExtensionProperty(eclSectionName, "MimeType", eclItem.MimeType); eclStubComponent.AddExtensionProperty(eclSectionName, "FileName", eclItem.Filename); eclStubComponent.AddExtensionProperty(eclSectionName, "TemplateFragment", eclItem.GetTemplateFragment(null)); IFieldSet eclExternalMetadataFieldSet = BuildExternalMetadataFieldSet(eclItem); if (eclExternalMetadataFieldSet != null) { eclStubComponent.ExtensionData["ECL-ExternalMetadata"] = eclExternalMetadataFieldSet; } } }
internal string ProcessEclXlink(XmlElement xlinkElement) { string eclStubComponentId = xlinkElement.GetAttribute("href", "http://www.w3.org/1999/xlink"); IContentLibraryContext eclContext; IContentLibraryMultimediaItem eclItem = GetEclItem(eclStubComponentId, out eclContext); // This may look a bit unusual, but we have to ensure that ECL Item members are accessed *before* the ECL Context is disposed. using (eclContext) { // Set additional ECL Item properties as data attributes on the XLink element xlinkElement.SetAttribute("data-eclId", eclItem.Id.ToString()); xlinkElement.SetAttribute("data-eclDisplayTypeId", eclItem.DisplayTypeId); if (!string.IsNullOrEmpty(eclItem.MimeType)) { xlinkElement.SetAttribute("data-eclMimeType", eclItem.MimeType); } if (!string.IsNullOrEmpty(eclItem.Filename)) { xlinkElement.SetAttribute("data-eclFileName", eclItem.Filename); } string eclTemplateFragment = eclItem.GetTemplateFragment(null); if (!string.IsNullOrEmpty(eclTemplateFragment)) { // Note that the entire Template Fragment gets stuffed in an XHTML attribute. // This may seem scary, but there is no limitation to the size of an XML attribute and the XLink element typically already has content. xlinkElement.SetAttribute("data-eclTemplateFragment", eclTemplateFragment); } // TODO: ECL external metadata (?) string directLinkToPublished = eclItem.GetDirectLinkToPublished(null); return(string.IsNullOrEmpty(directLinkToPublished) ? PublishBinaryContent(eclItem, eclStubComponentId) : directLinkToPublished); } }
private string PublishBinaryContent(IContentLibraryMultimediaItem eclItem, Component eclStubComponent) { IContentResult eclContent = eclItem.GetContent(_emptyAttributes); string uniqueFilename = $"{Path.GetFileNameWithoutExtension(eclItem.Filename)}_{eclStubComponent.Id.ToString().Substring(4)}{Path.GetExtension(eclItem.Filename)}"; return(_pipeline.RenderedItem.AddBinary(eclContent.Stream, uniqueFilename, string.Empty, eclStubComponent, eclContent.ContentType).Url); }
private string PublishBinaryContent(IContentLibraryMultimediaItem eclItem, string eclStubComponentId) { IContentResult eclContent = eclItem.GetContent(null); string uniqueFilename = string.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(eclItem.Filename), eclStubComponentId.Substring(4), Path.GetExtension(eclItem.Filename)); Tridion.ContentManager.ContentManagement.Component eclStubComponent = (Tridion.ContentManager.ContentManagement.Component)_engine.GetObject(eclStubComponentId); Tridion.ContentManager.Publishing.Rendering.Binary binary = (_binariesStructureGroup == null) ? _engine.PublishingContext.RenderedItem.AddBinary(eclContent.Stream, uniqueFilename, string.Empty, eclStubComponent, eclContent.ContentType) : _engine.PublishingContext.RenderedItem.AddBinary(eclContent.Stream, uniqueFilename, _binariesStructureGroup, string.Empty, eclStubComponent, eclContent.ContentType); _log.Debug(string.Format("Added binary content of ECL Item '{0}' (Stub Component: '{1}', MimeType: '{2}') as '{3}' in '{4}'.", eclItem.Id, eclStubComponentId, eclContent.ContentType, binary.Url, (_binariesStructureGroup == null) ? "(default)" : _binariesStructureGroup.PublishPath)); return(binary.Url); }
private static IList <ITemplateAttribute> CreateTemplateAttributes(IContentLibraryMultimediaItem eclItem) { IList <ITemplateAttribute> attributes = new List <ITemplateAttribute>(); if (eclItem.Width != null && eclItem.Width > 0) { attributes.Add(new NodeKeyValuePair(new KeyValuePair <string, string>("width", eclItem.Width.ToString()))); } if (eclItem.Height != null && eclItem.Height > 0) { attributes.Add(new NodeKeyValuePair(new KeyValuePair <string, string>("height", eclItem.Height.ToString()))); } attributes.Add(new NodeKeyValuePair(new KeyValuePair <string, string>("src", eclItem.Id.ToString()))); return(attributes); }
internal XmlElement BuildEntityModel(EntityModelData entityModelData, Component eclStubComponent) { IContentLibraryContext eclContext; IContentLibraryMultimediaItem eclItem = GetEclItem(eclStubComponent.Id, out eclContext); // This may look a bit unusual, but we have to ensure that ECL Item members are accessed *before* the ECL Context is disposed. using (eclContext) { BinaryContent eclStubBinaryContent = eclStubComponent.BinaryContent; string directLinkToPublished = eclItem.GetDirectLinkToPublished(_emptyAttributes); entityModelData.BinaryContent = new BinaryContentData { Url = string.IsNullOrEmpty(directLinkToPublished) ? PublishBinaryContent(eclItem, eclStubComponent) : directLinkToPublished, MimeType = eclItem.MimeType ?? eclStubBinaryContent.MultimediaType.MimeType, FileName = eclItem.Filename ?? eclStubBinaryContent.Filename, FileSize = eclStubComponent.BinaryContent.Size }; XmlElement externalMetadata = null; if (!string.IsNullOrEmpty(eclItem.MetadataXml)) { XmlDocument externalMetadataDoc = new XmlDocument(); externalMetadataDoc.LoadXml(eclItem.MetadataXml); externalMetadata = externalMetadataDoc.DocumentElement; } entityModelData.ExternalContent = new ExternalContentData { Id = eclItem.Id.ToString(), DisplayTypeId = eclItem.DisplayTypeId, TemplateFragment = eclItem.GetTemplateFragment(_emptyAttributes) // Note: not setting Metadata here, but returning the external metadata as raw XML. }; return(externalMetadata); } }
protected virtual string GetECLUrl(string uri) { Component c = (Component)engine.GetObject(uri); if (c == null) { throw new Exception(string.Format("Error loading item with uri {0}", uri)); } log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Instantiating a new ECL Session"); using (IEclSession localSession = SessionFactory.CreateEclSession(engine.GetSession())) { IEclUri eclUri = localSession.TryGetEclUriFromTcmUri(uri); if (eclUri != null) // this is an ECL item { log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Fetching IContentLibraryContext"); using (IContentLibraryContext context = localSession.GetContentLibrary(eclUri)) { try { IContentLibraryMultimediaItem item = null; // This is done this way to not have an exception thrown through GetItem, as stated // in the API doc. // The reason to do this, is because if there is an exception, // the ServiceChannel is going into the aborted state... log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Get Items"); // GetItems allows up to 20 (depending on config) connections. // After that any new connection is aborted / not created. var items = context.GetItems(new IEclUri[] { eclUri }); if (items != null && items.Count == 1) { item = (IContentLibraryMultimediaItem)items.First(); log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Item Fetched"); } if (item == null) { log.Warning(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Item with ECL URI: " + eclUri + " not found. This MM item is used in: " + c.Id); throw new Exception(string.Format("ECL item not found (ecl uri = {0}, tcm uri = {1}", eclUri, c.Id)); } string distributionUrl = item.GetDirectLinkToPublished(null); string result = distributionUrl.ToLower(); if (!string.IsNullOrEmpty(result)) { log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Returning: " + result); return(result); } } finally { log.Debug(System.Threading.Thread.CurrentThread.ManagedThreadId + ": Going out of the context using block statement."); } } } } return(string.Empty); }
/// <summary> /// Creates a new instance of a Templating Package item together with its corresponding a ECL Multimedia item /// </summary> /// <param name="packageItem">Templating Package item</param> /// <param name="eclItem">ECL Multimedia item</param> public EclItemInPackage(Item packageItem, IContentLibraryMultimediaItem eclItem) { PackageItem = packageItem; EclItem = eclItem; }
private string ImportSingleItem(IEclUri eclUri) { string id = "tcm:0-0-0"; IContentLibraryMultimediaItem eclItem = (IContentLibraryMultimediaItem)_eclContentLibraryContext.GetItem(eclUri); string extension = eclItem.Filename.Substring(eclItem.Filename.LastIndexOf('.') + 1); MemoryStream ms = null; string tempPath; try { // create some template attributes IList <ITemplateAttribute> attributes = CreateTemplateAttributes(eclItem); // determine if item has content or is available online string publishedPath = eclItem.GetDirectLinkToPublished(attributes); if (string.IsNullOrEmpty(publishedPath)) { // we can directly get the content IContentResult content = eclItem.GetContent(attributes); ms = new MemoryStream(); content.Stream.CopyTo(ms); ms.Position = 0; } else { // read the content from the publish path using (WebClient webClient = new WebClient()) { byte[] thumbnailData = webClient.DownloadData(publishedPath); ms = new MemoryStream(thumbnailData, false); } } // upload binary (using netTcp binding as configured in SDL Tridion, because this Model extension is running inside the UI) using (StreamUploadClient suClient = new StreamUploadClient("streamUpload_netTcp_2012")) { tempPath = suClient.UploadBinaryContent(eclItem.Filename, ms); } } finally { if (ms != null) { ms.Dispose(); } } // create tcm item var mmComponent = new ComponentData { Id = id, Title = eclItem.Title, Schema = new LinkToSchemaData { IdRef = _schemaUri }, LocationInfo = new LocationInfo { OrganizationalItem = new LinkToOrganizationalItemData { IdRef = _folderUri } } }; // put binary data in tcm item (using netTcp binding as configured in SDL Tridion, because this Model extension is running inside the UI) using (SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("netTcp_2012")) { // impersonate with current user client.Impersonate(_username); // set metadata var schemaFields = client.ReadSchemaFields(_schemaUri, true, new ReadOptions()); if (schemaFields.MetadataFields.Any()) { var fields = Fields.ForMetadataOf(schemaFields, mmComponent); if (!string.IsNullOrEmpty(eclItem.MetadataXml)) { XNamespace ns = GetNamespace(eclItem.MetadataXml); XDocument metadata = XDocument.Parse(eclItem.MetadataXml); var children = metadata.Element(ns + "Metadata").Descendants(); for (int i = 0; i < children.Count(); i++) { fields.AddFieldElement(new ItemFieldDefinitionData { Name = "data" }); var embeddedFields = fields["data"].GetSubFields(i); embeddedFields.AddFieldElement(new ItemFieldDefinitionData { Name = "key" }); embeddedFields.AddFieldElement(new ItemFieldDefinitionData { Name = "value" }); embeddedFields["key"].Value = children.ElementAt(i).Name.LocalName; embeddedFields["value"].Value = children.ElementAt(i).Value; } } mmComponent.Metadata = fields.ToString(); } // find multimedia type var list = client.GetSystemWideList(new MultimediaTypesFilterData()); var multimediaType = list.OfType <MultimediaTypeData>().Single(mt => mt.FileExtensions.Contains(extension)); // set BinaryContent of a component mmComponent.BinaryContent = new BinaryContentData { UploadFromFile = tempPath, Filename = eclItem.Filename, MultimediaType = new LinkToMultimediaTypeData { IdRef = multimediaType.Id } }; // create (and save) component ComponentData data = (ComponentData)client.Create(mmComponent, new ReadOptions()); id = data.Id; } //string result = string.Format("created {0}, from {1}, in {2}, using {3}, for {4}", id, eclUri, _folderUri, _schemaUri, _username); return(id); }
private static IList<ITemplateAttribute> CreateTemplateAttributes(IContentLibraryMultimediaItem eclItem) { IList<ITemplateAttribute> attributes = new List<ITemplateAttribute>(); if (eclItem.Width != null && eclItem.Width > 0) { attributes.Add(new NodeKeyValuePair(new KeyValuePair<string, string>("width", eclItem.Width.ToString()))); } if (eclItem.Height != null && eclItem.Height > 0) { attributes.Add(new NodeKeyValuePair(new KeyValuePair<string, string>("height", eclItem.Height.ToString()))); } attributes.Add(new NodeKeyValuePair(new KeyValuePair<string, string>("src", eclItem.Id.ToString()))); return attributes; }
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); } } } } } } }