Exemplo n.º 1
0
        protected virtual void AddDescendants(TaxonomyNode taxonomyNode, NavigationFilter filter, ILocalization localization)
        {
            using (new Tracer(taxonomyNode, filter, localization))
            {
                // First recurse (depth-first)
                IList <SitemapItem> children = taxonomyNode.Items;
                foreach (TaxonomyNode childNode in children.OfType <TaxonomyNode>())
                {
                    AddDescendants(childNode, filter, localization);
                }

                // Add descendants (on the way back)
                string taxonomyId;
                string keywordId;
                string pageId;
                ParseSitemapItemId(taxonomyNode.Id, out taxonomyId, out keywordId, out pageId);
                string taxonomyUri = localization.GetCmUri(taxonomyId, (int)ItemType.Category);
                string keywordUri  = string.IsNullOrEmpty(keywordId) ? taxonomyUri : localization.GetCmUri(keywordId, (int)ItemType.Keyword);

                IEnumerable <SitemapItem> additionalChildren = ExpandDescendants(keywordUri, taxonomyUri, filter, localization);
                foreach (SitemapItem additionalChildItem in additionalChildren.Where(childItem => children.All(i => i.Id != childItem.Id)))
                {
                    children.Add(additionalChildItem);
                }

                // Ensure that children are ordered correctly
                taxonomyNode.Items = SortTaxonomyNodes(children);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets a Navigation subtree for the given Sitemap Item.
        /// </summary>
        /// <param name="sitemapItemId">The context <see cref="SitemapItem"/> identifier. Can be <c>null</c>.</param>
        /// <param name="filter">The <see cref="NavigationFilter"/> used to specify which information to put in the subtree.</param>
        /// <param name="localization">The context <see cref="ILocalization"/>.</param>
        /// <returns>A set of Sitemap Items representing the requested subtree.</returns>
        public virtual IEnumerable <SitemapItem> GetNavigationSubtree(string sitemapItemId, NavigationFilter filter, ILocalization localization)
        {
            using (new Tracer(sitemapItemId, filter, localization))
            {
                if (string.IsNullOrEmpty(sitemapItemId))
                {
                    return(ExpandTaxonomyRoots(filter, localization));
                }

                // Extract Taxonomy TCM UI, Keyword TCM URI and/or Page TCM URI from the Sitemap Item ID
                string taxonomyId;
                string keywordId;
                string pageId;
                ParseSitemapItemId(sitemapItemId, out taxonomyId, out keywordId, out pageId);
                string taxonomyUri = localization.GetCmUri(taxonomyId, (int)ItemType.Category);
                string keywordUri  = string.IsNullOrEmpty(keywordId) ?  taxonomyUri : localization.GetCmUri(keywordId, (int)ItemType.Keyword);
                string pageUri     = localization.GetCmUri(pageId, (int)ItemType.Page);

                IEnumerable <SitemapItem> result = new SitemapItem[0];
                if (filter.IncludeAncestors)
                {
                    TaxonomyNode taxonomyRoot = null;
                    if (!string.IsNullOrEmpty(keywordId))
                    {
                        taxonomyRoot = ExpandAncestorsForKeyword(keywordUri, taxonomyUri, filter, localization);
                    }
                    else if (!string.IsNullOrEmpty(pageId))
                    {
                        taxonomyRoot = ExpandAncestorsForPage(pageUri, taxonomyUri, filter, localization);
                    }

                    if (taxonomyRoot != null)
                    {
                        if (filter.DescendantLevels != 0)
                        {
                            AddDescendants(taxonomyRoot, filter, localization);
                        }

                        result = new[] { taxonomyRoot };
                    }
                }
                else if (filter.DescendantLevels != 0 && string.IsNullOrEmpty(pageId))
                {
                    result = ExpandDescendants(keywordUri, taxonomyUri, filter, localization);
                }

                return(result);
            }
        }
        protected virtual object MapKeyword(KeywordModelData keywordModelData, Type targetType, ILocalization localization)
        {
            if (typeof(KeywordModel).IsAssignableFrom(targetType))
            {
                KeywordModel result;
                if (keywordModelData.SchemaId == null)
                {
                    result = new KeywordModel
                    {
                        ExtensionData = keywordModelData.ExtensionData
                    };
                }
                else
                {
                    MappingData keywordMappingData = new MappingData
                    {
                        SourceViewModel    = keywordModelData,
                        ModelType          = targetType,
                        PropertyValidation = new Validation
                        {
                            MainSchema       = SemanticMapping.GetSchema(keywordModelData.SchemaId, localization),
                            InheritedSchemas = GetInheritedSemanticSchemas(keywordModelData as ViewModelData, localization)
                        },
                        MetadataFields = keywordModelData.Metadata,
                        Localization   = localization
                    };

                    result = (KeywordModel)CreateViewModel(keywordMappingData);
                }

                result.Id          = keywordModelData.Id;
                result.Title       = keywordModelData.Title;
                result.Description = keywordModelData.Description ?? string.Empty;
                result.Key         = keywordModelData.Key ?? string.Empty;
                result.TaxonomyId  = keywordModelData.TaxonomyId;

                return(result);
            }

            if (targetType == typeof(Tag))
            {
                return(new Tag
                {
                    DisplayText = GetKeywordDisplayText(keywordModelData),
                    Key = keywordModelData.Key,
                    TagCategory = localization.GetCmUri(keywordModelData.TaxonomyId, (int)ItemType.Category)
                });
            }

            if (targetType == typeof(bool))
            {
                string key = string.IsNullOrEmpty(keywordModelData.Key) ? keywordModelData.Title : keywordModelData.Key;
                return(Convert.ToBoolean(key));
            }

            return(GetKeywordDisplayText(keywordModelData));
        }
        protected virtual IEnumerable <string> GetFieldValuesAsStrings(object fieldValues, MappingData mappingData, bool resolveComponentLinks)
        {
            if (!resolveComponentLinks)
            {
                // Handle Component Links here, because standard model mapping will resolve them.
                ILocalization localization = mappingData.Localization;
                if (fieldValues is EntityModelData)
                {
                    return(new[] { localization.GetCmUri(((EntityModelData)fieldValues).Id) });
                }
                if (fieldValues is EntityModelData[])
                {
                    return(((EntityModelData[])fieldValues).Select(emd => localization.GetCmUri(emd.Id)));
                }
            }

            // Use standard model mapping to map the field to a list of strings.
            return((IEnumerable <string>)MapField(fieldValues, typeof(List <string>), null, mappingData));
        }
Exemplo n.º 5
0
 protected virtual SitemapItem[] ExpandClassifiedPages(Keyword keyword, string taxonomyId, ILocalization localization)
 {
     using (new Tracer(keyword.KeywordUri, taxonomyId, localization))
     {
         // Return SitemapItems for all classified Pages (ordered by Page Title, including sequence prefix if any)
         PageMetaFactory pageMetaFactory     = new PageMetaFactory(localization.GetCmUri());
         IPageMeta[]     classifiedPageMetas = pageMetaFactory.GetTaxonomyPages(keyword, includeBranchedFacets: false);
         SitemapItem[]   result = classifiedPageMetas.Select(pageMeta => CreateSitemapItem(pageMeta, taxonomyId)).ToArray();
         return(result);
     }
 }
        protected virtual string GetLinkUrl(EntityModelData entityModelData, ILocalization localization)
        {
            if (entityModelData.LinkUrl != null)
            {
                return(entityModelData.LinkUrl);
            }

            Log.Debug($"Link URL for Entity Model '{entityModelData.Id}' not resolved by Model Service.");
            string componentUri = localization.GetCmUri(entityModelData.Id);

            return(SiteConfiguration.LinkResolver.ResolveLink(componentUri));
        }
Exemplo n.º 7
0
        protected virtual IEnumerable <SitemapItem> ExpandTaxonomyRoots(NavigationFilter filter, ILocalization localization)
        {
            using (new Tracer(filter, localization))
            {
                TaxonomyFactory taxonomyFactory = new TaxonomyFactory();
                string[]        taxonomyIds     = taxonomyFactory.GetTaxonomies(localization.GetCmUri());

                int                   depth          = filter.DescendantLevels > 0 ? (filter.DescendantLevels - 1) : filter.DescendantLevels;
                TaxonomyFilter        taxonomyFilter = new DepthFilter(depth, DepthFilter.FilterDown);
                IEnumerable <Keyword> taxonomyRoots  = taxonomyIds.Select(id => taxonomyFactory.GetTaxonomyKeywords(id, taxonomyFilter));

                return(taxonomyRoots.Select(kw => CreateTaxonomyNode(kw, depth, filter, localization)));
            }
        }
Exemplo n.º 8
0
        private static ResultSet ExecuteSmartTargetQuery(SmartTargetPageModel smartTargetPageModel, ILocalization localization)
        {
            using (new Tracer(smartTargetPageModel, localization))
            {
                TcmUri pageUri        = new TcmUri(localization.GetCmUri(smartTargetPageModel.Id, (int)ItemType.Page));
                TcmUri publicationUri = new TcmUri(localization.GetCmUri());

                ClaimStore claimStore = AmbientDataContext.CurrentClaimStore;
                string     triggers   = AmbientDataHelper.GetTriggers(claimStore);

                QueryBuilder queryBuilder = new QueryBuilder();
                queryBuilder.Parse(triggers);
                queryBuilder.AddCriteria(new PublicationCriteria(publicationUri));
                queryBuilder.AddCriteria(new PageCriteria(pageUri));

                // Adding all the page regions to the query for having only 1 query a page
                foreach (SmartTargetRegion region in smartTargetPageModel.Regions.OfType <SmartTargetRegion>())
                {
                    queryBuilder.AddCriteria(new RegionCriteria(region.Name));
                }

                return(queryBuilder.Execute());
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Gets the cached local file for a given binary Id.
        /// </summary>
        /// <param name="binaryId">The binary Id.</param>
        /// <param name="localization">The Localization.</param>
        /// <returns>The path to the local file.</returns>
        internal string GetCachedFile(int binaryId, ILocalization localization)
        {
            string baseDir       = AppDomain.CurrentDomain.BaseDirectory;
            string localFilePath = $"{baseDir}/{localization.BinaryCacheFolder}";

            using (new Tracer(binaryId, localization, localFilePath))
            {
                string publicationUri = localization.GetCmUri();

                if (!localization.IsXpmEnabled)
                {
                    try
                    {
                        string[] files = Directory.GetFiles(localFilePath, $"{binaryId}_*",
                                                            SearchOption.TopDirectoryOnly);
                        if (files.Length > 0)
                        {
                            localFilePath = files[0];
                            if (IsCached(() => GetBinaryLastPublishDate(binaryId, localization), localFilePath,
                                         localization))
                            {
                                return(localFilePath);
                            }
                        }
                    }
                    catch (Exception)
                    {
                        // Our binary cache folder probably doesn't exist.
                    }
                }

                // Binary does not exist or cached binary is out-of-date
                BinaryMeta binaryMeta = GetBinaryMeta(binaryId, localization);
                if (binaryMeta == null)
                {
                    throw new DxaItemNotFoundException(binaryId.ToString(), localization.Id);
                }
                BinaryFactory binaryFactory = new BinaryFactory();
                BinaryData    binaryData    = binaryFactory.GetBinary(GetPublicationId(publicationUri), binaryMeta.Id, binaryMeta.VariantId);
                string        ext           = Path.GetExtension(binaryMeta.Path) ?? "";
                localFilePath = $"{localFilePath}/{localization.Id}-{binaryId}{ext}";
                WriteBinaryToFile(binaryData.Bytes, localFilePath, null);
                return(localFilePath);
            }
        }
Exemplo n.º 10
0
        protected virtual string ResolveNavigationTaxonomyUri(ILocalization localization)
        {
            using (new Tracer(localization))
            {
                TaxonomyFactory taxonomyFactory = new TaxonomyFactory();
                string[]        taxonomyIds     = taxonomyFactory.GetTaxonomies(localization.GetCmUri());

                Keyword navTaxonomyRoot = taxonomyIds.Select(id => taxonomyFactory.GetTaxonomyKeyword(id)).FirstOrDefault(tax => tax.KeywordName.Contains(TaxonomyNavigationMarker));
                if (navTaxonomyRoot == null)
                {
                    Log.Warn("No Navigation Taxonomy Found in Localization [{0}]. Ensure a Taxonomy with '{1}' in its title is published.", localization, TaxonomyNavigationMarker);
                    return(string.Empty);
                }

                Log.Debug("Resolved Navigation Taxonomy: {0} ('{1}')", navTaxonomyRoot.TaxonomyUri, navTaxonomyRoot.KeywordName);

                return(navTaxonomyRoot.TaxonomyUri);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets the cached local file for a given URL path.
        /// </summary>
        /// <param name="urlPath">The URL path.</param>
        /// <param name="localization">The Localization.</param>
        /// <returns>The path to the local file.</returns>
        internal string GetCachedFile(string urlPath, ILocalization localization)
        {
            string baseDir       = AppDomain.CurrentDomain.BaseDirectory;
            string localFilePath = $"{baseDir}/{urlPath}";

            if (File.Exists(localFilePath))
            {
                // If our resource exists on the filesystem we can assume static content that is
                // manually added to web application.
                return(localFilePath);
            }
            // Attempt cache location with fallback to retrieval from CIL. Note we don't check cache
            // when running under XPM
            localFilePath = $"{baseDir}/{localization.BinaryCacheFolder}/{urlPath}";
            using (new Tracer(urlPath, localization, localFilePath))
            {
                Dimensions dimensions;
                urlPath = StripDimensions(urlPath, out dimensions);
                string publicationUri = localization.GetCmUri();
                if (!localization.IsXpmEnabled && File.Exists(localFilePath))
                {
                    if (IsCached(() => GetBinaryLastPublishDate(urlPath, publicationUri), localFilePath, localization))
                    {
                        return(localFilePath);
                    }
                }

                // Binary does not exist or cached binary is out-of-date
                BinaryMeta binaryMeta = GetBinaryMeta(urlPath, publicationUri);
                if (binaryMeta == null)
                {
                    throw new DxaItemNotFoundException(urlPath, localization.Id);
                }
                BinaryFactory binaryFactory = new BinaryFactory();
                BinaryData    binaryData    = binaryFactory.GetBinary(GetPublicationId(publicationUri), binaryMeta.Id, binaryMeta.VariantId);

                WriteBinaryToFile(binaryData.Bytes, localFilePath, dimensions);
                return(localFilePath);
            }
        }
Exemplo n.º 12
0
        private void PopulateSmartTargetRegions(SmartTargetPageModel smartTargetPageModel, ILocalization localization)
        {
            // Execute a ST Query for all SmartTargetRegions on the Page.
            ResultSet resultSet = ExecuteSmartTargetQuery(smartTargetPageModel, localization);

            Log.Debug($"SmartTarget query returned {resultSet.Promotions.Count} Promotions.");

            string promotionViewName = localization.GetConfigValue(PromotionViewNameConfig);

            if (String.IsNullOrEmpty(promotionViewName))
            {
                Log.Warn($"No View name for SmartTarget Promotions is configured on CM-side ({PromotionViewNameConfig})");
                promotionViewName = "SmartTarget:Entity:Promotion";
            }
            Log.Debug($"Using Promotion View '{promotionViewName}'");

            // TODO: we shouldn't access HttpContext in a Model Builder.
            HttpContext httpContext = HttpContext.Current;

            if (httpContext == null)
            {
                throw new DxaException("HttpContext is not available.");
            }

            List <string>     itemsAlreadyOnPage        = new List <string>();
            ExperimentCookies existingExperimentCookies = CookieProcessor.GetExperimentCookies(httpContext.Request);
            ExperimentCookies newExperimentCookies      = new ExperimentCookies();

            // Filter the Promotions for each SmartTargetRegion
            foreach (SmartTargetRegion smartTargetRegion in smartTargetPageModel.Regions.OfType <SmartTargetRegion>())
            {
                string regionName = smartTargetRegion.Name;

                List <string>        itemsOutputInRegion = new List <string>();
                ExperimentDimensions experimentDimensions;
                List <Promotion>     promotions = new List <Promotion>(resultSet.Promotions);
                ResultSet.FilterPromotions(promotions, regionName, smartTargetRegion.MaxItems, smartTargetPageModel.AllowDuplicates, itemsOutputInRegion,
                                           itemsAlreadyOnPage, ref existingExperimentCookies, ref newExperimentCookies,
                                           out experimentDimensions);

                if (experimentDimensions != null)
                {
                    // The SmartTarget API doesn't set all ExperimentDimensions properties, but they are required by the ExperimentTrackingHandler (see CRQ-1667).
                    experimentDimensions.PublicationId = localization.GetCmUri();
                    experimentDimensions.PageId        = localization.GetCmUri(smartTargetPageModel.Id, (int)ItemType.Page);
                    experimentDimensions.Region        = smartTargetRegion.Name;
                }

                if (localization.IsXpmEnabled)
                {
                    // The SmartTarget API provides the entire XPM markup tag; put it in XpmMetadata["Query"]. See SmartTargetRegion.GetStartQueryXpmMarkup.
                    smartTargetRegion.XpmMetadata = new Dictionary <string, object>
                    {
                        { "Query", ResultSet.GetExperienceManagerMarkup(smartTargetRegion.Name, smartTargetRegion.MaxItems, promotions) }
                    };
                }

                // Create SmartTargetPromotion Entity Models for visible Promotions in the current SmartTargetRegion.
                // It seems that ResultSet.FilterPromotions doesn't really filter on Region name, so we do post-filtering here.
                foreach (Promotion promotion in promotions.Where(promotion => promotion.Visible && promotion.Regions.Contains(regionName)))
                {
                    SmartTargetPromotion smartTargetPromotion = CreatePromotionEntity(promotion, promotionViewName, smartTargetRegion.Name, localization, experimentDimensions);

                    if (!smartTargetRegion.HasSmartTargetContent)
                    {
                        // Discard any fallback content coming from Content Manager
                        smartTargetRegion.Entities.Clear();
                        smartTargetRegion.HasSmartTargetContent = true;
                    }

                    smartTargetRegion.Entities.Add(smartTargetPromotion);
                }
            }

            if (newExperimentCookies.Count > 0)
            {
                smartTargetPageModel.ExperimentCookies = newExperimentCookies;
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Populates a Dynamic List by executing the query it specifies.
        /// </summary>
        /// <param name="dynamicList">The Dynamic List which specifies the query and is to be populated.</param>
        /// <param name="localization">The context Localization.</param>
        public virtual void PopulateDynamicList(DynamicList dynamicList, ILocalization localization)
        {
            using (new Tracer(dynamicList, localization))
            {
                SimpleBrokerQuery simpleBrokerQuery = dynamicList.GetQuery(localization) as SimpleBrokerQuery;
                if (simpleBrokerQuery == null)
                {
                    throw new DxaException($"Unexpected result from {dynamicList.GetType().Name}.GetQuery: {dynamicList.GetQuery(localization)}");
                }

                Common.Interfaces.IQueryProvider brokerQuery = new BrokerQueryProvider();
                string[] componentUris = brokerQuery.ExecuteQuery(simpleBrokerQuery).ToArray();
                Log.Debug($"Broker Query returned {componentUris.Length} results. HasMore={brokerQuery.HasMore}");

                if (componentUris.Length > 0)
                {
                    Type resultType = dynamicList.ResultType;
                    ComponentMetaFactory componentMetaFactory = new ComponentMetaFactory(localization.GetCmUri());
                    dynamicList.QueryResults = componentUris
                                               .Select(c => ModelBuilderPipeline.CreateEntityModel(CreateEntityModelData(componentMetaFactory.GetMeta(c)), resultType, localization))
                                               .ToList();
                }

                dynamicList.HasMore = brokerQuery.HasMore;
            }
        }
Exemplo n.º 14
0
 private static string GetPublicationUri(Tridion.ContentManager.TcmUri tcmUri, ILocalization localization)
 => (localization == null) ? $"tcm:0-{tcmUri.PublicationId}-1" : localization.GetCmUri();