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);
        }
Exemplo n.º 6
0
        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;
 }
Exemplo n.º 10
0
        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;
        }
Exemplo n.º 12
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);
                                }
                            }
                        }
                    }
                }
            }
        }