Example #1
0
        /// <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);
                }
            }
        }
        protected string RunTemplate(Type templateType, IdentifiableObject inputItem, Template template = null)
        {
            RenderedItem testRenderedItem = CreateTestRenderedItem(inputItem, template);
            TestEngine   testEngine       = new TestEngine(testRenderedItem);
            Package      testPackage      = new Package(testEngine);

            Type        inputItemType        = inputItem.GetType();
            string      inputItemName        = inputItemType.Name;
            ContentType inputItemContentType = new ContentType($"tridion/{inputItemType.Name.ToLower()}");

            testPackage.PushItem(inputItemName, testPackage.CreateTridionItem(inputItemContentType, inputItem));

            ITemplate testTemplate = Activator.CreateInstance(templateType) as ITemplate;

            Assert.IsNotNull(testTemplate, "testTemplate");

            testTemplate.Transform(testEngine, testPackage);

            Item outputItem = testPackage.GetByName(Package.OutputName);

            Assert.IsNotNull(outputItem, "outputItem");

            string result = outputItem.GetAsString();

            Assert.IsNotNull(result, "result");

            Console.WriteLine("Output Item:");
            Console.WriteLine(result);

            return(result);
        }
Example #3
0
        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;
        }
Example #4
0
        protected Package RunTemplate(Type templateType, IdentifiableObject inputItem, out RenderedItem renderedItem, Template template = null)
        {
            renderedItem = CreateTestRenderedItem(inputItem, template);
            TestEngine testEngine  = new TestEngine(renderedItem);
            Package    testPackage = new Package(testEngine);

            Type        inputItemType        = inputItem.GetType();
            string      inputItemName        = inputItemType.Name;
            ContentType inputItemContentType = new ContentType($"tridion/{inputItemType.Name.ToLower()}");

            testPackage.PushItem(inputItemName, testPackage.CreateTridionItem(inputItemContentType, inputItem));

            ITemplate testTemplate = Activator.CreateInstance(templateType) as ITemplate;

            Assert.IsNotNull(testTemplate, "testTemplate");

            testTemplate.Transform(testEngine, testPackage);

            return(testPackage);
        }
 public static string FormatIdentifier(this IdentifiableObject identifiableObject) =>
 $"{identifiableObject.GetType().Name} '{identifiableObject.Title}' ({identifiableObject.Id})";
        /// <summary>
        /// Entry point for resolver.
        /// </summary>
        /// <param name="item">Item to resolve</param>
        /// <param name="instruction">Resolve instruction</param>
        /// <param name="context">Publish context</param>
        /// <param name="resolvedItems">Final items to resolve</param>
        public void Resolve(IdentifiableObject item, ResolveInstruction instruction, PublishContext context,
                            Tridion.Collections.ISet <ResolvedItem> resolvedItems)
        {
            if (instruction.Purpose != ResolvePurpose.Publish && instruction.Purpose != ResolvePurpose.RePublish ||
                _maxRecurseDepth == 0)
            {
                return;
            }
            _log.Debug("DXA Custom Resolver started...");
            _log.Debug("Loading global app data:");
            const string appId = "dxa:CustomResolver";

            try
            {
                var appData = context.Session.SystemManager.LoadGlobalApplicationData(appId);
                if (appData != null)
                {
                    _log.Debug("Found configuration for custom resolver in global app data. Attempting to parse.");
                    string xml = string.Empty;
                    if (appData.TypeId?.StartsWith("XmlElement:") ?? false)
                    {
                        _log.Debug($"Found configuration using XElement appData type.");
                        string      @string     = Encoding.UTF8.GetString(appData.Data);
                        XmlDocument xmlDocument = new XmlDocument();
                        xmlDocument.LoadXml(@string);
                        xml = xmlDocument.DocumentElement?.OuterXml;
                    }
                    if (string.IsNullOrEmpty(xml))
                    {
                        _log.Debug("Assuming string content for xml.");
                        xml = Encoding.Unicode.GetString(appData.Data);
                    }
                    _log.Debug($"xml={xml}");
                    XElement parsedXml = XElement.Parse(xml);
                    foreach (XElement xe in parsedXml.Elements())
                    {
                        if (!xe.Name.LocalName.Equals("RecurseDepth"))
                        {
                            continue;
                        }
                        _log.Debug($"Found RecurseDepth value of '{xe.Value}'.");
                        _maxRecurseDepth = int.Parse(xe.Value);
                        break; // only one setting at moment
                    }
                }
                else
                {
                    _log.Debug(
                        $"Custom resolver configuration not found in global app data for '{appId}'. Using default settings.");
                    _maxRecurseDepth = -1;
                }
            }
            catch (Exception e)
            {
                _log.Debug(
                    $"Exception occured when reading global app data for application id '{appId}'. Using default settings.");
                _log.Debug(e.Message);
                _maxRecurseDepth = -1;
            }

            _log.Debug($"Using _maxRecurseDepth={_maxRecurseDepth}");

            try
            {
                var sourceItem = (RepositoryLocalObject)item;

                _log.Debug($"Analyzing source item of type: {item.GetType().Name} with id: {item.Id} and title: {item.Title}");

                var contextPublication = (Publication)sourceItem.ContextRepository;
                var filter             = new ComponentTemplatesFilter(item.Session)
                {
                    AllowedOnPage = false,
                    BaseColumns   = ListBaseColumns.IdAndTitle
                };
                const string dataPresentationTemplateTitle = "Generate Data Presentation";
                var          dataPresentationTemplate      = contextPublication.GetComponentTemplates(filter).FirstOrDefault(
                    ct => ct.Title == dataPresentationTemplateTitle);
                if (dataPresentationTemplate == null)
                {
                    _log.Debug("No 'Generate Data Presentation' component template found. Skipping custom resolver.");
                    return;
                }
                var       resolved = new HashSet <IdentifiableObject>();
                Stopwatch t        = new Stopwatch();
                t.Start();

                HashSet <TcmUri> alreadyResolved = new HashSet <TcmUri>();
                foreach (var x in resolvedItems)
                {
                    alreadyResolved.Add(x.Item.Id);
                }

                List <ResolvedItem> resolvedItemsCopy = new List <ResolvedItem>(resolvedItems);
                foreach (var resolvedItem in resolvedItemsCopy)
                {
                    foreach (var dataPresentation in ResolveDataPresentations(resolvedItem.Item, dataPresentationTemplate, resolved, 0))
                    {
                        if (alreadyResolved.Contains(dataPresentation.Item.Id))
                        {
                            _log.Debug($"  > Already resolved item '{dataPresentation.Item.Title}' with id: {dataPresentation.Item.Id}");
                            continue;
                        }
                        _log.Debug($"  > Resolved item '{dataPresentation.Item.Title}' with id: {dataPresentation.Item.Id}");
                        alreadyResolved.Add(dataPresentation.Item.Id);
                        resolvedItems.Add(dataPresentation);
                    }
                }

                t.Stop();
                _log.Debug($"DXA Custom Resolver took {t.ElapsedMilliseconds}ms to complete.");
            }
            catch (Exception e)
            {
                _log.Debug($"Exception occured: {e.Message}");
                _log.Debug($"Stacktrace: {e.StackTrace}");
                throw;
            }
        }
        private List <ResolvedItem> ResolveDataPresentations(IdentifiableObject item,
                                                             ComponentTemplate template, HashSet <IdentifiableObject> resolved, int recurseLevel)
        {
            _log.Debug($"Analyzing item for resolving of type: '{item.GetType().Name}' id: '{item.Id}' title: '{item.Title}'");
            List <ResolvedItem> toResolve = new List <ResolvedItem>();

            if (!ContinueRecursion(recurseLevel))
            {
                _log.Debug($"Reached max recusion level when trying to resolve item {item.Id}, skipping.");
                return(toResolve);
            }
            List <Component> components = new List <Component>();

            if (item is Page)
            {
                var page = (Page)item;
                _log.Debug($"Resolving page '{page.Title}' Id={page.Id}");
                if (resolved.Contains(page))
                {
                    _log.Debug("  * already resolved this page, skipping !");
                    return(toResolve);
                }
                components.AddRange(GatherComponentPresentations(page).Select(cp => cp.Component));
            }
            if (item is Component)
            {
                _log.Debug($"Resolving component '{item.Title}' Id={item.Id}");
                components.Add(item as Component);
            }
            if (components.Count <= 0)
            {
                return(toResolve);
            }
            var toProcess = new HashSet <Component>();
            var depths    = new Dictionary <Component, int>();

            for (int i = 0; i < components.Count; i++)
            { // note: avoiding recursive approach here so we can truely do infinite depth without stack overflows
                var c     = components[i];
                int depth = recurseLevel;
                if (depths.ContainsKey(c))
                {
                    depth = depths[c];
                }
                if (!ContinueRecursion(depth))
                {
                    continue;
                }
                if (toProcess.Contains(c))
                {
                    continue;
                }
                toProcess.Add(c);
                List <Component> linked = GatherLinkedComponents(c);
                foreach (var linkedComponent in linked)
                {
                    if (!ContinueRecursion(depth + 1))
                    {
                        break;
                    }
                    if (toProcess.Contains(linkedComponent))
                    {
                        continue;
                    }
                    components.Add(linkedComponent);
                    if (depths.ContainsKey(linkedComponent))
                    {
                        depths[linkedComponent] = depth + 1;
                    }
                    else
                    {
                        depths.Add(linkedComponent, depth + 1);
                    }
                }
            }
            toResolve.AddRange(toProcess.Select(
                                   component => ResolveComponent(component, template, resolved, recurseLevel)).Where(r => r != null));
            return(toResolve);
        }
Example #8
0
        /// <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);
                }
            }
        }