public static void UpdateDynamicPageFormFormulas(AgilityContent existingContent, AgilityContent deltaContent)
        {
            if (deltaContent == null || deltaContent.DataSet == null)
            {
                return;
            }



            Dictionary <string, List <int> > dpIndex = BaseCache.GetDynamicPageIndex();

            List <int> lstPageIDs = null;

            if (dpIndex.TryGetValue(deltaContent.ReferenceName.ToLowerInvariant(), out lstPageIDs))
            {
                foreach (int pageID in lstPageIDs)
                {
                    AgilityPage page = BaseCache.GetPageFromID(pageID, deltaContent.LanguageCode, AgilityContext.WebsiteName, null);
                    if (page != null)
                    {
                        //update all of the DynamicPageIndexes that this content appears on...
                        BaseCache.UpdateDynamicPageFormulaIndex(page, existingContent, deltaContent, deltaContent.ReferenceName, existingContent == null);
                    }
                }
            }
        }
        public static void UpdateDynamicPageIndex(AgilityPage page)
        {
            if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName) ||
                !string.IsNullOrEmpty(page.DynamicPageParentFieldName))
            {
                if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName.ToLowerInvariant()))
                {
                    BaseCache.UpdateDynamicPageIndex(page.ID, page.DynamicPageContentViewReferenceName.ToLowerInvariant());
                }

                //update the Dynamic Page Formula Index that use this page...
                BaseCache.ClearDynamicDynamicPageFormulaIndex(page);
            }
        }
        private static AgilityPage GetPage(HttpContext context)
        {
            AgilityPage _page = context.Items["Agility.Web.AgilityContext.Page"] as AgilityPage;

            if (_page == null)
            {
                string url = AgilityContext.HttpContext.Request.Path;

                url = HttpUtility.UrlPathEncode(url);

                _page = Agility.Web.Data.GetPage(url);

                context.Items["Agility.Web.AgilityContext.Page"] = _page;
            }
            return(_page);
        }
        public async Task <HtmlString> InvokeAsync()
        {
            AgilityContext.HttpContext = HttpContext;

            AgilityPage currentPage = AgilityContext.Page;

            if (currentPage == null)
            {
                return(null);
            }

            StringBuilder sb = new StringBuilder(Environment.NewLine);

            string scriptTopGlobal;
            string scriptBottomGlobal;

            string scriptBottomPage = null;

            //output the id of any page a/b test experiments



            var experiments = BaseCache.GetExperiments(AgilityContext.WebsiteName);
            var experiment  = experiments.GetForPage(currentPage.ID);

            if (experiment != null)
            {
                if (experiment.Variants != null &&
                    experiment.Variants.Any(v => !string.IsNullOrWhiteSpace(v.URL)))
                {
                    //PAGE REDIRECT EXPERIMENTS ONLY
                    AgilityContext.ExperimentKeys.Add(experiment.Key);


                    sb.AppendLine("<script type='text/javascript'>");

                    //get the winner
                    if (experiment.WinningVariant != null)
                    {
                        sb.AppendFormat("window.AgilityExperimentWinningVariant = {{ experiment: '{0}' variant: {1}, url: '{2}' }};",
                                        experiment.Key,
                                        experiment.WinningVariant.ID,
                                        AgilityHelpers.ResolveUrl(experiment.WinningVariant.URL)
                                        );
                    }
                    else
                    {
                        sb.Append("window.AgilityExperimentVariants = [");
                        foreach (var v in experiment.Variants)
                        {
                            sb.AppendFormat("{{ experiment: '{0}', variant: {1}, url: '{2}' }},",
                                            experiment.Key,
                                            v.ID,
                                            AgilityHelpers.ResolveUrl(v.URL)
                                            );
                        }

                        sb.AppendLine("];");
                        sb.AppendLine("</script>");
                    }
                }
            }
            else if (currentPage.ServerPage.ExperimentIDs != null)
            {
                foreach (int exId in currentPage.ServerPage.ExperimentIDs)
                {
                    experiment = experiments.GetExperiment(exId);
                    if (experiment != null)
                    {
                        AgilityContext.ExperimentKeys.Add(experiment.Key);
                    }
                }
            }


            //add the Javascript tracking stuff
            if (currentPage.IncludeInStatsTracking)
            {
                //global script
                if (!string.IsNullOrEmpty(AgilityContext.Domain.StatsTrackingScript))
                {
                    scriptTopGlobal = AgilityContext.Domain.StatsTrackingScript;

                    if (scriptTopGlobal.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) != -1)
                    {
                        scriptBottomGlobal = scriptTopGlobal.Substring(scriptTopGlobal.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) + AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR.Length);
                        scriptTopGlobal    = scriptTopGlobal.Substring(0, scriptTopGlobal.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR));
                    }

                    if (!string.IsNullOrEmpty(scriptTopGlobal))
                    {
                        sb.Append(scriptTopGlobal);
                        sb.Append(Environment.NewLine);
                    }
                }
            }

            string scriptTopPage = null;

            //custom script for this page
            if (!string.IsNullOrEmpty(currentPage.CustomAnalyticsScript))
            {
                scriptTopPage = currentPage.CustomAnalyticsScript;

                if (scriptTopPage.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) != -1)
                {
                    scriptBottomPage = scriptTopPage.Substring(scriptTopPage.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR) + AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR.Length);
                    scriptTopPage    = scriptTopPage.Substring(0, scriptTopPage.IndexOf(AgilityHelpers.GLOBAL_SCRIPT_SEPARATOR));
                }

                if (!string.IsNullOrEmpty(scriptTopPage))
                {
                    sb.Append(scriptTopPage);
                    sb.Append(Environment.NewLine);
                }
            }

            return(new HtmlString(sb.ToString()));
        }
Example #5
0
        public override void ExecuteResult(ActionContext context)
        {
            try
            {
                EmptyResult empty = new EmptyResult();

                //check if the request has been already served (set in route constraint)
                object constraintCheck = context.HttpContext.Items["Agility.Web.RequestPreviouslyHandledInRouteConstraint"];
                if (constraintCheck is bool && ((bool)constraintCheck))
                {
                    empty.ExecuteResult(context);
                    return;
                }


                HttpRequest  Request  = context.HttpContext.Request;
                HttpResponse Response = context.HttpContext.Response;


                //initialize the offline processing...

                //HACK: OFFLINE: this should be started in the Startup
                //if (!OfflineProcessing.IsOfflineThreadRunning)
                //{
                //    OfflineProcessing.StartOfflineThread();
                //}


                string url    = UriHelper.GetEncodedUrl(Request);
                string rawUrl = Request.GetEncodedPathAndQuery();

                //check if this is Robots.txt and a publishwithagility.com domain (used for staging only)
                if ((
                        Request.Host.Value.IndexOf(".publishwithagility.com", StringComparison.CurrentCultureIgnoreCase) != -1 ||
                        Request.Host.Value.IndexOf(".azurewebsites.net", StringComparison.CurrentCultureIgnoreCase) != -1) &&
                    string.Equals(rawUrl, "/robots.txt", StringComparison.CurrentCultureIgnoreCase))
                {
                    Response.ContentType = "text/plain";

                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("User-agent: *");
                    sb.Append("Disallow: /");
                    var task = Response.WriteAsync(sb.ToString());
                    task.Wait();

                    empty.ExecuteResult(context);
                    AgilityCache.TurnOffCacheInProgress();
                    return;
                }


                //don't allow ANY urls to end with /
                if (!Current.Settings.IgnoreTrailingSlash)
                {
                    if (rawUrl != "/" && rawUrl.EndsWith("/"))
                    {
                        string newUrl = rawUrl.TrimEnd('/');

                        AgilityHttpModule.RedirectResponse(newUrl, 301);
                        AgilityCache.TurnOffCacheInProgress();
                        return;
                    }
                }



                if (AgilityContext.BuildAgilityContext())
                {
                    empty.ExecuteResult(context);


                    AgilityCache.TurnOffCacheInProgress();

                    return;
                }

                //pre-process the request for any channel or redirections that we encounter...
                string pagePath = AgilityPagePath;
                if (!IgnorePrechecks)
                {
                    if (AgilityHttpModule.HandleChannelsAndRedirects(ref pagePath, LanguageCode))
                    {
                        empty.ExecuteResult(context);

                        AgilityCache.TurnOffCacheInProgress();

                        return;
                    }
                }


                //use the first page in the sitemap if there is no page passed in...
                if (string.IsNullOrEmpty(pagePath) || pagePath == "/" || pagePath == "~/")
                {
                    pagePath = BaseCache.GetDefaultPagePath(AgilityContext.LanguageCode, AgilityContext.WebsiteName, string.Empty);
                }

                //check to see if the site should be in "preview mode"
                if (AgilityHttpModule.CheckPreviewMode(context.HttpContext))
                {
                    empty.ExecuteResult(context);

                    AgilityCache.TurnOffCacheInProgress();

                    return;
                }



                AgilityPage page = null;

                if (!string.IsNullOrEmpty(pagePath))
                {
                    //add the ~ if neccessary
                    if (!pagePath.StartsWith("~/"))
                    {
                        if (!pagePath.StartsWith("/"))
                        {
                            pagePath = string.Format("~/{0}", pagePath);
                        }
                        else
                        {
                            pagePath = string.Format("~{0}", pagePath);
                        }
                    }


                    page = Agility.Web.Data.GetPage(pagePath, LanguageCode);

                    //check if this page is a folder, kick out...
                    if (page != null &&
                        string.IsNullOrEmpty(page.TemplatePath) &&
                        page.TemplateID < 1 &&
                        string.IsNullOrEmpty(page.RedirectURL))
                    {
                        page = null;
                    }
                }


                if (AgilityContext.IsResponseEnded)
                {
                    //check if we've ended the response...
                    empty.ExecuteResult(context);

                    AgilityCache.TurnOffCacheInProgress();

                    return;
                }

                if (page == null)
                {
                    //possibly route the page if it is a page template...

                    string aspxPath = context.HttpContext.Request.PathBase;

                    int previewIndex = aspxPath.IndexOf("TemplatePreview/", StringComparison.CurrentCultureIgnoreCase);

                    if (previewIndex > -1)
                    {
                        aspxPath = aspxPath.Substring(previewIndex + "TemplatePreview/".Length);
                        aspxPath = string.Format("~/{0}", aspxPath);

                        if (!aspxPath.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase))
                        {
                            //assume we wanted to render a .cshtml file
                            aspxPath = string.Format("{0}.cshtml", aspxPath);
                        }


                        //load the page def in Preview mode...
                        int pageDefinitionID = 0;
                        if (int.TryParse(Request.Query["agilityPageDefinitionID"], out pageDefinitionID) &&
                            pageDefinitionID > 0)
                        {
                            AgilityContext.IsTemplatePreview = true;

                            string pageTitle = string.Empty;

                            AgilityContentServer.AgilityPageDefinition _currentPageDefinition = BaseCache.GetPageDefinition(pageDefinitionID, AgilityContext.WebsiteName);
                            if (_currentPageDefinition != null)
                            {
                                AgilityContext.CurrentPageTemplateInPreview = _currentPageDefinition;

                                pageTitle = string.Format("Template Preview - {0}", _currentPageDefinition.Name);

                                ViewData.Model = new AgilityTemplateModel()
                                {
                                    Page = new AgilityPage()
                                    {
                                        Title = pageTitle
                                    }
                                };

                                ViewResult templateView = new ViewResult()
                                {
                                    //TODO: handle template preview with inline code...
                                    ViewName = _currentPageDefinition.TemplatePath,
                                    ViewData = ViewData
                                };

                                return;
                            }
                        }
                    }

                    //

                    //404 - we can't load the page, so we have to throw a 404
                    //TODO: figure out how to return a 404
                    context.HttpContext.Response.StatusCode = 404;
                    return;
                }



                //if we get here and we don't have a page, throw a 404
                if (page == null)
                {
                    context.HttpContext.Response.StatusCode = 404;
                    return;
                }


                //set the dynamic page formula items from the last ones that were loaded...
                AgilityContext.DynamicPageFormulaItem = AgilityContext.LastLoadedDynamicPageFormulaItem;

                //check if this page is a redirect
                if (!string.IsNullOrEmpty(page.RedirectURL))
                {
                    //redirect to the link specified on the page
                    AgilityHttpModule.RedirectResponse(page.RedirectURL);
                    AgilityCache.TurnOffCacheInProgress();
                    return;
                }


                //set the current language and culture based on the language code...
                AgilityHttpModule.SetLanguageAndCultureBasedOnPage(page);

                //set the page in context (Context.items)
                AgilityContext.Page = page;

                //setup ouput caching
                AgilityHttpModule.SetupOutputCaching(context.HttpContext.Request, context.HttpContext.Response, page);

                //assemble the model data
                ViewData.Model = new AgilityTemplateModel()
                {
                    Page = page
                };

                ViewData["Title"] = page.Title;

                string templatePath = string.Empty;

                DataView dv = Data.GetContentView(AgilityDynamicCodeFile.REFNAME_AgilityPageCodeTemplates, AgilityDynamicCodeFile.LANGUAGECODE_CODE);
                if (dv != null && dv.Count > 0)
                {
                    string    filter = string.Format("ReferenceName = '{0}' AND Visible = true", page.TemplateID);
                    DataRow[] rows   = dv.Table.Select(filter);
                    if (rows.Length > 0)
                    {
                        templatePath = string.Format("~/Views/{0}/DynamicAgilityCode/{1}/{2}.cshtml",
                                                     rows[0]["VersionID"],
                                                     AgilityDynamicCodeFile.REFNAME_AgilityPageCodeTemplates,
                                                     page.TemplateID);
                    }

                    else
                    {
                    }
                }

                if (string.IsNullOrEmpty(templatePath))
                {
                    //if it's not in code, check the regular template path
                    templatePath = page.TemplatePath;
                }

                if (string.IsNullOrEmpty(templatePath))
                {
                    //still null? throw an error...
                    throw new ApplicationException("The template for this page is not available.");
                }


                //get the view engine
                var tempdata = HtmlHelperViewExtensions.GetServiceOrFail <ITempDataDictionaryFactory>(context.HttpContext);
                var engine   = HtmlHelperViewExtensions.GetServiceOrFail <IRazorViewEngine>(context.HttpContext);


                ViewEngineResult viewResult = engine.GetView(null, templatePath, true);

                var tempDataDict = tempdata.GetTempData(context.HttpContext);

                StringWriter sw = new StringWriter();

                if (!viewResult.Success || viewResult?.View == null)
                {
                    throw new ApplicationException("The template for this page is not available.");
                }



                var viewContext = new ViewContext(context, viewResult.View, ViewData, tempDataDict, sw, new HtmlHelperOptions());

                //render the view...
                var t = viewResult.View.RenderAsync(viewContext);
                t.Wait();

                string s = sw.GetStringBuilder().ToString();


                //set the content type
                Response.ContentType = "text/html";

                t = Response.WriteAsync(s);
                t.Wait();


                //ViewResult view = new ViewResult()
                //{
                //	ViewName = templatePath,
                //	ViewData = ViewData
                //};



                //view.ExecuteResult(context);
            }
            //TODO: do we get an HttpException here?
            //catch (HttpException hex)
            //{

            //	if (hex.InnerException != null)
            //	{
            //		if (hex.InnerException.InnerException != null && hex.InnerException.InnerException is HttpException)
            //		{
            //			//http exceptions thrown from Partial Controllers are buried...
            //			throw hex.InnerException.InnerException;
            //		}

            //	}

            //	throw hex;

            //}
            catch (Exception ex)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("ViewData: ").AppendLine();
                foreach (string key in ViewData.Keys)
                {
                    sb.AppendFormat("{0}: {1}", key, ViewData[key]).AppendLine();
                }


                ApplicationException aex = new ApplicationException(sb.ToString(), ex);

                AgilityHttpModule.HandleIntializationException(aex);
            }
        }
        private static void RedirectToDynamicPreviewUrl(Dictionary <string, AgilityRouteCacheItem> routes, string path, string languageCode)
        {
            List <string> urlPaths = new List <string>();

            string[] pathParts   = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            string   staticRoute = string.Empty;

            AgilityRouteCacheItem routeItem = null;

            //keep some parent objects...
            AgilityPage            parentPage    = null;
            DynamicPageFormulaItem dpItemParent  = null;
            AgilityContent         parentContent = null;

            int previewContentID = -1;
            int previewVersionID = -1;

            if (!int.TryParse(AgilityContext.HttpContext.Request.Query["previewContentID"], out previewContentID))
            {
                if (!int.TryParse(AgilityContext.HttpContext.Request.Query["previewVersionID"], out previewVersionID))
                {
                    int.TryParse(AgilityContext.HttpContext.Request.Query["ContentID"], out previewContentID);
                }
            }

            foreach (string pathPart in pathParts)
            {
                string testStaticRoute = string.Format("{0}/{1}", staticRoute, pathPart);

                if (routes.TryGetValue(testStaticRoute, out routeItem))
                {
                    int pageID = routeItem.PageID;



                    //get the page...
                    AgilityPage page = BaseCache.GetPageFromID(pageID, languageCode, AgilityContext.WebsiteName, null);
                    if (page == null)
                    {
                        //if the page is null at this point, assume it's a folder page and jsut insert the static path...
                        urlPaths.Add(pathPart);
                        staticRoute = testStaticRoute;
                        continue;
                    }

                    string contentReferenceName = null;
                    int    parentContentID      = -1;



                    if (string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName) &&
                        string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                    {
                        //static page...
                        urlPaths.Add(pathPart);
                    }
                    else
                    {
                        //dynamic page..
                        if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName))
                        {
                            contentReferenceName = page.DynamicPageContentViewReferenceName;

                            if (!string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                            {
                                if (parentPage == null || dpItemParent == null)
                                {
                                    return;
                                }

                                //we have to match up to the parent page...
                                parentContentID = dpItemParent.ContentID;
                            }
                        }
                        else if (!string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                        {
                            //get the dynamic content from the PARENT page
                            if (parentPage == null || dpItemParent == null)
                            {
                                return;
                            }

                            object obj = dpItemParent.GetContentItemValue(page.DynamicPageParentFieldName);
                            if (obj != null)
                            {
                                contentReferenceName = string.Format("{0}", obj);
                            }
                        }

                        if (string.IsNullOrEmpty(contentReferenceName))
                        {
                            return;
                        }


                        //get the content first if we are in development or staging mode...
                        AgilityContentServer.AgilityContent content = BaseCache.GetContent(contentReferenceName, languageCode, AgilityContext.WebsiteName);


                        //get the dynamic content for this page
                        DynamicPageFormulaItemIndex dpIndex = BaseCache.GetDynamicPageFormulaIndex(pageID, contentReferenceName, languageCode, page, true);
                        if (dpIndex == null || dpIndex.Count == 0)
                        {
                            return;
                        }


                        DynamicPageFormulaItem dpItem = null;


                        //try to use the preview url
                        if (previewVersionID > 0 || previewContentID > 0)
                        {
                            DataRow row = null;
                            if (previewContentID > 0)
                            {
                                row = content.GetItemByContentID(previewContentID);
                            }
                            else
                            {
                                DataRow[] rows = content.DataSet.Tables["ContentItems"].Select(string.Format("VersionID = {0}", previewVersionID));
                                if (rows.Length > 0)
                                {
                                    row = rows[0];
                                }
                            }

                            if (row != null)
                            {
                                string pageName = string.Format("/{0}", DynamicPageFormulaItem.ResolveFormula(page.DynamicPageName, row, true)).ToLowerInvariant();
                                if (dpIndex.TryGetValue(pageName, out dpItem))
                                {
                                    //adjust the parent if we need to...
                                    if (!string.IsNullOrEmpty(page.DynamicPageParentFieldName) && dpItemParent != null)
                                    {
                                        //grab the parent id...
                                        object parentIDObj = dpItem.GetContentItemValue(page.DynamicPageParentFieldName);
                                        if (parentIDObj != null)
                                        {
                                            string parentIDStr = string.Format("{0}", parentIDObj);
                                            if (parentIDStr.IndexOf(",") != -1)
                                            {
                                                parentIDStr = parentIDStr.Substring(0, parentIDStr.IndexOf(","));
                                            }
                                            int adjustedParentID = -1;
                                            if (int.TryParse(parentIDStr, out adjustedParentID))
                                            {
                                                if (dpItemParent.ContentID != adjustedParentID)
                                                {
                                                    // if the parent id DOES NOT match, we need to do some URL jigging...
                                                    DataRow parentRow = parentContent.GetItemByContentID(adjustedParentID);

                                                    parentContentID = adjustedParentID;
                                                    if (parentRow != null)
                                                    {
                                                        //get the parent page name and switch it up in the url..
                                                        string parentPageName = string.Format("/{0}", DynamicPageFormulaItem.ResolveFormula(parentPage.DynamicPageName, parentRow, true)).ToLowerInvariant();
                                                        urlPaths[urlPaths.Count - 1] = parentPageName.Substring(1);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }


                        if (dpItem == null)
                        {
                            //use the first one if we don't have an item yet...
                            dpItem = dpIndex.Values.FirstOrDefault();
                        }


                        if (parentContentID > 1 && previewVersionID < 1 && previewContentID < 1)
                        {
                            //unless we have a parent id to follow...

                            foreach (DynamicPageFormulaItem item in dpIndex.Values)
                            {
                                object testParentContentIDObj = item.GetContentItemValue(page.DynamicPageParentFieldName);
                                if (testParentContentIDObj != null)
                                {
                                    int    testParentContentID    = -1;
                                    string testParentContentIDStr = string.Format("{0}", testParentContentIDObj);

                                    if (int.TryParse(testParentContentIDStr, out testParentContentID))
                                    {
                                        //if the value is an int, test for equality...
                                        if (parentContentID == testParentContentID)
                                        {
                                            dpItem = item;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        //value is NOT an int, test for "in" '[id],' or ',[id],' or ',[id]'
                                        if (testParentContentIDStr.StartsWith(string.Format("{0},", parentContentID)) ||
                                            testParentContentIDStr.EndsWith(string.Format(",{0}", parentContentID)) ||
                                            testParentContentIDStr.Contains(string.Format(",{0},", parentContentID)))
                                        {
                                            dpItem = item;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (dpItem == null)
                        {
                            return;
                        }


                        urlPaths.Add(dpItem.Name.TrimStart("/".ToCharArray()));
                        dpItemParent  = dpItem;
                        parentContent = content;
                    }

                    staticRoute = testStaticRoute;
                    parentPage  = page;
                }
                else
                {
                    //if we can't find a static route, kick out.
                    return;
                }
            }

            if (urlPaths.Count > 0)
            {
                StringBuilder sbUrl = new StringBuilder("~/");
                sbUrl.Append(string.Join("/", urlPaths.ToArray()));

                if (AgilityContext.HttpContext.Request.Path.Value.EndsWith(".aspx", StringComparison.CurrentCultureIgnoreCase))
                {
                    sbUrl.Append(".aspx");
                }
                if (!string.IsNullOrEmpty(AgilityContext.HttpContext.Request.QueryString.Value))
                {
                    sbUrl.Append(AgilityContext.HttpContext.Request.QueryString.Value);
                }

                string redirectUrl = sbUrl.ToString();

                //strip off the querystrings that we don't want...
                redirectUrl = Agility.Web.Util.Url.RemoveQueryString(redirectUrl, "ContentID&VersionID&previewContentID&previewVersionID");


                Agility.Web.HttpModules.AgilityHttpModule.RedirectResponse(redirectUrl, 301);

                AgilityContext.IsResponseEnded = true;
            }
        }
        private static ResolvedPage ResolvePage(
            ref Dictionary <string, AgilityRouteCacheItem> routes,
            AgilityRouteCacheItem routeItem,
            string dynamicRoute,
            string languageCode,
            string websiteName,
            ref List <ResolvedPage> resolvedPages,
            string url)
        {
            AgilityPage page = BaseCache.GetPageFromID(routeItem.PageID, languageCode, websiteName, url);



            if (string.IsNullOrEmpty(dynamicRoute))
            {
                //make sure we have the page, if not, then kick out
                if (page == null)
                {
                    return(null);
                }

                if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName) ||
                    !string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                {
                    //we have NO dynamic route, but the page is dynamic, kick out
                    return(null);
                }

                //not a dynamic page (a static page nested under a dynamic one...)
                return(new ResolvedPage(page, null));
            }
            else
            {
                //resolve the Dynamic Route

                if (string.IsNullOrEmpty(routeItem.ChildDynamicPagePath))
                {
                    //no dynamic page attached to this static page.. kick out
                    return(null);
                }

                //get the route item for the child dynamic page
                if (!routes.TryGetValue(routeItem.ChildDynamicPagePath, out routeItem))
                {
                    return(null);
                }



                //get the dynamic page
                page = BaseCache.GetPageFromID(routeItem.PageID, languageCode, websiteName, url);

                if (page == null)
                {
                    Agility.Web.Tracing.WebTrace.WriteWarningLine(string.Format("Routing: could not load page with id: {0} in language {1} websitename {2} url {3}", routeItem.PageID, languageCode, websiteName, url));
                    return(null);
                }


                if (string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName) &&
                    string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                {
                    //we have a dynamic route, but the page is not dynamic, kick out
                    return(null);
                }

                string contentReferenceName = page.DynamicPageContentViewReferenceName;
                int    parentContentID      = -1;
                if (string.IsNullOrEmpty(contentReferenceName))
                {
                    if (!string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                    {
                        for (int i = resolvedPages.Count - 1; i >= 0; i--)
                        {
                            DynamicPageFormulaItem dpParent = resolvedPages[i].DynamicPageItem;
                            if (dpParent == null)
                            {
                                continue;
                            }

                            //get the content reference name from the parent page...
                            object fieldValueObj = dpParent.GetContentItemValue(page.DynamicPageParentFieldName);
                            if (fieldValueObj != null)
                            {
                                contentReferenceName = fieldValueObj as string;
                                break;
                            }
                        }
                    }
                }
                else if (!string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                {
                    //filter the dynamic page list by the parent field...
                    for (int i = resolvedPages.Count - 1; i >= 0; i--)
                    {
                        DynamicPageFormulaItem dpParent = resolvedPages[i].DynamicPageItem;
                        if (dpParent == null)
                        {
                            continue;
                        }
                        if (dpParent != null)
                        {
                            parentContentID = dpParent.ContentID;
                            break;
                        }
                    }
                    if (parentContentID < 1)
                    {
                        return(null);
                    }
                }

                //if we didn't resolve a content view, kick out...
                if (string.IsNullOrEmpty(contentReferenceName))
                {
                    return(null);
                }

                //create/update the dynamic page index with this page id and dynamic page list reference name
                BaseCache.UpdateDynamicPageIndex(page.ID, contentReferenceName);

                //get the content first if we are in development or staging mode...
                if (AgilityContext.CurrentMode == Enum.Mode.Staging || Agility.Web.Configuration.Current.Settings.DevelopmentMode)
                {
                    AgilityContentServer.AgilityContent content = BaseCache.GetContent(contentReferenceName, page.LanguageCode, AgilityContext.WebsiteName);
                }

                //get the dynamic page list dictionary for this page (this method also updates if neccessary)...
                DynamicPageFormulaItemIndex dpIndex = BaseCache.GetDynamicPageFormulaIndex(page.ID, contentReferenceName, page.LanguageCode, page, true);

                DynamicPageFormulaItem dpItem = null;
                if (dpIndex == null || !dpIndex.TryGetValue(dynamicRoute, out dpItem))
                {
                    //check if friendly-making the route would result in a match
                    string friendly = DynamicPageFormulaItem.MakePathFriendly(dynamicRoute);
                    if (friendly == dynamicRoute || !dpIndex.TryGetValue(friendly, out dpItem))
                    {
                        //we didn't find the item, and making the given path friendly didn't work either. Kick out.
                        return(null);
                    }

                    //there's an item, but only after fixing the path. redirect.
                    string baseUrl     = Data.GetSiteMapNode(page.ID).PagePath;
                    string redirectUrl = baseUrl.LastIndexOf('/') > 0
                                                                                   ? baseUrl.Substring(0, baseUrl.LastIndexOf('/')) + friendly
                                                                                   : friendly;
                    if (url.ToLower().EndsWith(".aspx"))
                    {
                        redirectUrl += ".aspx";
                    }

                    //add the current query string..
                    string query = AgilityContext.HttpContext.Request.QueryString.Value;
                    if (!string.IsNullOrEmpty(query))
                    {
                        redirectUrl += query;
                    }

                    //set the url to get this page, and the ActionResult or HttpModule will 301 redirect to it.
                    ResolvedPage resolvedPage = new ResolvedPage(page, dpItem);
                    resolvedPage.RedirectURL = redirectUrl;
                    return(resolvedPage);
                }

                //check parent content if neccessary
                if (parentContentID > 0 &&
                    !string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                {
                    object testParentContentIDObj = dpItem.GetContentItemValue(page.DynamicPageParentFieldName);

                    if (testParentContentIDObj != null)
                    {
                        int    testParentContentID    = -1;
                        string testParentContentIDStr = string.Format("{0}", testParentContentIDObj);

                        if (int.TryParse(testParentContentIDStr, out testParentContentID))
                        {
                            //if the value is an int, test for equality...
                            if (parentContentID != testParentContentID)
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            //value is NOT an int, test for "in" '[id],' or ',[id],' or ',[id]'
                            if (!testParentContentIDStr.StartsWith(string.Format("{0},", parentContentID)) &&
                                !testParentContentIDStr.EndsWith(string.Format(",{0}", parentContentID)) &&
                                !testParentContentIDStr.Contains(string.Format(",{0},", parentContentID)))
                            {
                                return(null);
                            }
                        }
                    }
                }

                return(new ResolvedPage(page, dpItem));
            }
        }
        internal static List <ResolvedPage> ResolveRoutePath(string path, string languageCode)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }



            path = path.ToLowerInvariant();

            List <ResolvedPage> lstResolvedPages = new List <ResolvedPage>();

            AgilityRouteCacheItem routeItem = null;

            string websiteName = AgilityContext.WebsiteName;
            Dictionary <string, AgilityRouteCacheItem> routes = AgilityRouteTable.GetRouteTable(languageCode, AgilityContext.CurrentChannel.ID);

            #region *** STATIC PAGE ***

            //STATIC PAGE

            if (routes.TryGetEncoded(path, out routeItem))
            {
                var appRelativeCurrentExecutionFilePath = "/";

                //try to resolve the entire path first... if that works, we can kick out right away...
                AgilityPage page = BaseCache.GetPageFromID(routeItem.PageID, languageCode, websiteName, appRelativeCurrentExecutionFilePath);
                if (page == null)
                {
                    return(null);
                }
                if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName) ||
                    !string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                {
                    //we are on a static page, but we don't have the dynamic part of the URL in place... s

                    if (Agility.Web.HttpModules.AgilityHttpModule.CheckPreviewMode(AgilityContext.HttpContext))
                    {
                        AgilityContext.IsResponseEnded = true;
                    }
                    else                     //if (AgilityContext.IsPreview || Configuration.Current.Settings.DevelopmentMode)
                    {
                        //add in the dynamic part of the URL if we are in preview mode...
                        RedirectToDynamicPreviewUrl(routes, path, languageCode);
                    }

                    return(null);
                }

                lstResolvedPages.Add(new ResolvedPage(page));
                return(lstResolvedPages);
            }
            #endregion

            //DYNAMIC PAGE
            //if we can't find the path, start peeling off parts of the path left to right and get the
            //static paths combined with the dynamic paths

            string[] pathParts = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            //if there are less than 2 parts to the path, it CAN'T be a dynamic path...
            if (pathParts.Length < 2)
            {
                return(null);
            }

            string staticRoute  = "";
            string dynamicRoute = string.Empty;
            AgilityRouteCacheItem testRouteItem = null;
            routeItem = null;

            ResolvedPage parentPage = null;


            //Assume we are a WEB SITE (not a virtual directory)
            string url = "/";

            //loop the rest of the path...
            bool foundRoute        = false;  // signal that we found a route, we can return safely
            bool foundDynamicRoute = false;  //signal that we found a dynamic route

            var pathIndex = -1;

            foreach (string pathPart in pathParts)
            {
                pathIndex++;
                foundRoute = false;             // init to not found for every iteration

                string testStaticRoute = string.Format("{0}/{1}", staticRoute, pathPart);

                //check for a secondary static route (eg: /Static1/Dyn1/Dyn2/Static2
                if (routes.TryGetValue(testStaticRoute, out testRouteItem))
                {
                    foundRoute = true;                 // static route means we found a route

                    //found a static route, add it to the list of resolved pages...
                    AgilityPage page = BaseCache.GetPageFromID(testRouteItem.PageID, languageCode, websiteName, null);
                    if (page == null)
                    {
                        //assume a null page means a folder...
                        lstResolvedPages.Add(new ResolvedPage(null));
                        staticRoute = testStaticRoute;
                        routeItem   = testRouteItem;
                        continue;
                    }


                    //todo...
                    ////check if this page is routing to a dynamic page redirect... (/path/dynamic-page/item-[contentid]
                    //if (!string.IsNullOrEmpty(page.DynamicPageContentViewReferenceName)
                    //	|| !string.IsNullOrEmpty(page.DynamicPageParentFieldName))
                    //{
                    //	if (pathParts.Length == pathIndex + 1)
                    //	{

                    //		xxx

                    //		//check for item- in the last part of the path to see if this is a redirect...
                    //	}
                    //}


                    parentPage = new ResolvedPage(page);
                    lstResolvedPages.Add(parentPage);

                    routeItem   = testRouteItem;
                    staticRoute = testStaticRoute;
                }
                else
                {
                    //did not find a static route, add this to the dynamic route...
                    dynamicRoute = string.Format("{0}/{1}", dynamicRoute, pathPart);

                    //if we have a dynamic Route left over, and the static page was set, then we have our first page candidate..
                    if (routeItem != null)
                    {
                        //derive a resolved page from routeItem and dynamic route...
                        ResolvedPage resolvedPage = ResolvePage(ref routes, routeItem, dynamicRoute, languageCode, websiteName, ref lstResolvedPages, url);
                        if (resolvedPage != null)
                        {
                            foundRoute        = true;
                            foundDynamicRoute = true;

                            parentPage = resolvedPage;
                            lstResolvedPages.Add(resolvedPage);

                            parentPage   = resolvedPage;
                            dynamicRoute = string.Empty;

                            //now the NEXT route item becomes the child of this dynamic page..
                            if (!string.IsNullOrEmpty(routeItem.ChildDynamicPagePath) &&
                                routes.TryGetValue(routeItem.ChildDynamicPagePath, out testRouteItem))
                            {
                                staticRoute = routeItem.ChildDynamicPagePath;
                                routeItem   = testRouteItem;
                            }
                        }
                    }
                }
            }

            //if we didn't manage to find a dynamic page in there, return null;
            if (foundRoute && foundDynamicRoute)
            {
                return(lstResolvedPages);
            }

            return(null);
        }
        internal static string GetStatusPanelScript()
        {
            //Add the Style Sheets for the StatusBar and Edit In Place:
            StringBuilder sb = new StringBuilder();
            //HACK

            bool isPublished = false;
            bool containsUnpublishedModules = false;

            string pageTemplatePath = string.Empty;
            int    pageTemplateID   = -1;
            int    pageID           = -1;

            if (AgilityContext.Page != null)
            {
                AgilityPage page = AgilityContext.Page;

                pageID = page.ID;
                if (page.IsPublished)
                {
                    isPublished = true;
                }

                if (!string.IsNullOrEmpty(page.TemplatePath) && page.TemplateID > 0)
                {
                    pageTemplatePath = page.TemplatePath;
                    if (pageTemplatePath.StartsWith("~/"))
                    {
                        pageTemplatePath = pageTemplatePath.Substring(1);

                        string appPath = "/";
                        if (appPath != "/")
                        {
                            pageTemplatePath = string.Format("{0}{1}{2}", appPath, "/TemplatePreview", pageTemplatePath);
                        }
                        else
                        {
                            pageTemplatePath = string.Format("{0}{1}", "/TemplatePreview", pageTemplatePath);
                        }
                    }

                    pageTemplateID = page.TemplateID;
                }



                bool switchMode = false;
                if (AgilityContext.CurrentMode == Agility.Web.Enum.Mode.Live)
                {
                    //if the site is in live mode, switch to staging to check if any modules are required publishing.
                    switchMode = true;
                    AgilityContext.CurrentMode = Agility.Web.Enum.Mode.Staging;
                }

                //check if there are any modules that have not yet been publish
                foreach (ContentSection sect in AgilityContext.Page.ContentSections)
                {
                    if (sect.ModuleID > 0)
                    {
                        AgilityContentServer.AgilityModule module = BaseCache.GetModule(sect.ModuleID, AgilityContext.WebsiteName);
                        if (module != null && !module.IsPublished && module.IsPublishedSpecified)
                        {
                            containsUnpublishedModules = true;
                        }
                    }
                }

                if (switchMode)
                {
                    AgilityContext.CurrentMode = Agility.Web.Enum.Mode.Live;
                }
            }

            //generate the preview key
            string securityKey = Current.Settings.SecurityKey;

            byte[] data = UnicodeEncoding.Unicode.GetBytes(string.Format("{0}_{1}_Preview", -1, securityKey));
            SHA512 shaM = new SHA512Managed();

            byte[] result = shaM.ComputeHash(data);


            string previewKey  = Convert.ToBase64String(result);
            string appendQuery = string.Format("agilitypreviewkey={0}&agilityts={1}&lang={2}",
                                               HttpUtility.UrlEncode(previewKey),
                                               DateTime.Now.ToString("yyyyMMddhhmmss"),
                                               HttpUtility.UrlEncode(AgilityContext.LanguageCode));

            string pageUrl = AgilityContext.UrlForPreviewBar;

            if (string.IsNullOrEmpty(pageUrl))
            {
                pageUrl = AgilityContext.HttpContext.Request.GetEncodedUrl();
            }


            string innerUrl = Agility.Web.Util.Url.ModifyQueryString(
                HttpUtility.UrlPathEncode(pageUrl),
                appendQuery,
                "ispreview");

            string subject = string.Format("Agility {0} Preview", AgilityContext.WebsiteName);
            string body    = string.Format("Click the link below to preview the {0} site:\n{1}\n____________________\nSent from Agility\nhttp://www.agilitycms.com",
                                           AgilityContext.WebsiteName,
                                           innerUrl);

            string previewURL = string.Format("mailto:?subject={0}&body={1}",
                                              HttpUtility.UrlEncode(subject).Replace("+", "%20"),
                                              HttpUtility.UrlEncode(body).Replace("+", "%20"));

            //channel listing
            string[] channels = (from c in BaseCache.GetDigitalChannels(AgilityContext.WebsiteName).Channels
                                 select string.Format("{{Name:\"{0}\",ID:'{1}'}}", c.DisplayName.Replace("\"", "\\\""), c.ReferenceName)).ToArray();

            string uniqueID = Guid.NewGuid().ToString();

            string previewDateStr = AgilityContext.PreviewDateTime.ToString("yyyy-M-d h:mm tt", CultureInfo.InvariantCulture);

            if (AgilityContext.PreviewDateTime == DateTime.MinValue)
            {
                previewDateStr = string.Empty;
            }

            //output the script for the onload
            sb.Append("<script type='text/javascript'>");

            //output the context object
            sb.AppendFormat(@"var agilityContextObj = {{
					currentMode:""{0}"", 
					isPreview:{1}, 
					isTemplatePreview:{2}, 
					languageCode:""{3}"", 
					websiteName:""{4}"", 
					isDevelopmentMode:{5}, 
					controlUniqueID:""{6}"", 
					previewDateTime:""{7}"",
					isPublished:{8}, 
					containsUnpublishedModules:{9}, 
					pageTemplatePath:""{10}"", 
					pageTemplateID:{11}, 
					previewURL:""{12}"",
					cookieDomain:""{13}"",
					pageID:""{14}"",
					errorLink:{15},
					channel:'{16}',
					channels:[{17}]
				}}; "                ,
                            new object[] {
                AgilityContext.CurrentMode,                                        //0
                AgilityContext.IsPreview.ToString().ToLowerInvariant(),            //1
                AgilityContext.IsTemplatePreview.ToString().ToLowerInvariant(),    //2
                AgilityContext.LanguageCode,                                       //3
                AgilityContext.WebsiteName.Replace("\"", "\\\"").Replace(" ", ""), //4
                Current.Settings.DevelopmentMode.ToString().ToLowerInvariant(),    //5
                uniqueID,                                                          //6
                previewDateStr,                                                    //7
                isPublished.ToString().ToLowerInvariant(),                         //8
                containsUnpublishedModules.ToString().ToLowerInvariant(),          //9
                pageTemplatePath.Replace("\"", "\\\""),                            //10
                pageTemplateID,                                                    //11
                previewURL.Replace("\"", "\\\""),                                  //12
                Current.Settings.CookieDomain,                                     //13
                pageID,
                Current.Settings.DevelopmentMode && WebTrace.HasErrorOccurred ? string.Format("'{0}?enc={1}'", Agility.Web.HttpModules.AgilityHttpModule.ECMS_ERRORS_KEY, HttpUtility.UrlEncode(WebTrace.GetEncryptionQueryStringForLogFile(DateTime.Now))) : "null",
                AgilityContext.CurrentChannel.ReferenceName,
                string.Join(",", channels)
            });
            sb.Append(Environment.NewLine);
            sb.Append("var agilityLanguages = [");

            foreach (Language lang in AgilityContext.Domain.Languages)
            {
                sb.AppendFormat("['{0}', '{1}'],", lang.LanguageName, lang.LanguageCode);
            }
            sb = sb.Remove(sb.Length - 1, 1);
            sb.Append("];");
            sb.Append(Environment.NewLine);
            sb.Append("</script>");

            sb.Append("<script type='text/javascript' src='https://media.agilitycms.com/preview-bar/2018-11/agility-preview-bar.es5.min.js'></script>");


            return(sb.ToString());
        }
        public static Task <IHtmlContent> RenderContentZone(this IViewComponentHelper component, AgilityPage page, string zoneName)
        {
            try
            {
                HttpContext currentContext = AgilityContext.HttpContext;

                String websiteName = AgilityContext.WebsiteName;
                if (page == null)
                {
                    if (AgilityContext.IsTemplatePreview)
                    {
                        //TODO render the template preview


                        //var templates = from cs in AgilityContext.CurrentPageTemplateInPreview.ContentSections
                        //				where string.Equals(cs.Name, zoneName, StringComparison.CurrentCultureIgnoreCase)
                        //				orderby cs.XModuleOrder
                        //				select cs;
                        //TextWriter tw = helper.ViewContext.Writer;

                        //foreach (var cs in templates)
                        //{
                        //	tw.Write(string.Format("<div class=\"AgilityContentSectionDefinition\"><div class=\"ContentSectionTitle\">{0}</div></div>", cs.Name));
                        //}
                    }

                    return(Task.Run <IHtmlContent>(() => { return new HtmlString("TODO: implement template preview"); }));
                }



                //regular page rendering
                var sections = from cs in page.ContentSections
                               where string.Equals(cs.Name, zoneName, StringComparison.CurrentCultureIgnoreCase)
                               orderby cs.ModuleOrder
                               select cs;

                List <Task <string> > sectionTasks = new List <Task <string> >();
                DateTime dtStart = DateTime.Now;

                foreach (var cs in sections)
                {
                    //only continue if we have a content ref name...
                    if (string.IsNullOrEmpty(cs.ContentReferenceName))
                    {
                        continue;
                    }

                    //keep track of the various way this module can be rendered
                    List <ModuleRender> renders = new List <ModuleRender>()
                    {
                        new ModuleRender()
                        {
                            ContentReferenceName = cs.ContentReferenceName
                        }
                    };

                    //if this content zone is part of a Module AB test Experiment
                    if (cs.ExperimentID > 0)
                    {
                        var lst = BaseCache.GetExperiments(AgilityContext.WebsiteName);
                        AgilityContentServer.AgilityExperiment experiment = lst.GetExperiment(cs.ExperimentID);

                        if (experiment != null)
                        {
                            foreach (var variant in experiment.Variants.Where(v => !string.IsNullOrWhiteSpace(v.ContentReferenceName)))
                            {
                                renders.Add(new ModuleRender()
                                {
                                    ContentReferenceName = variant.ContentReferenceName,
                                    Variant = variant
                                });
                            }
                        }
                    }

                    foreach (ModuleRender moduleRender in renders)
                    {
                        try
                        {
                            string contentReferenceName = moduleRender.ContentReferenceName;

                            Agility.Web.AgilityContentServer.AgilityContent moduleContent = BaseCache.GetContent(contentReferenceName, AgilityContext.LanguageCode, websiteName);
                            if (moduleContent == null ||
                                moduleContent.DataSet == null ||
                                moduleContent.DataSet.Tables["ContentItems"] == null ||
                                moduleContent.DataSet.Tables["ContentItems"].Rows.Count == 0)
                            {
                                continue;
                            }


                            DataRowView drv = moduleContent.DataSet.Tables["ContentItems"].DefaultView[0];

                            int moduleContentID = -1;
                            int moduleVersionID = -1;

                            if (!int.TryParse($"{drv["ContentID"]}", out moduleContentID))
                            {
                                moduleContentID = -1;
                            }
                            if (!int.TryParse($"{drv["VersionID"]}", out moduleVersionID))
                            {
                                moduleVersionID = -1;
                            }


                            Agility.Web.AgilityContentServer.AgilityModule module = BaseCache.GetModule(cs.ModuleID, websiteName);
                            if (module == null)
                            {
                                continue;
                            }


                            object model = new AgilityModuleModel()
                            {
                                ModuleContentName = contentReferenceName,
                                ModuleProperties  = drv,
                                LanguageCode      = AgilityContext.LanguageCode
                            };

                            string viewComponentName  = null;
                            string agilityCodeRefName = null;

                            using (StringReader sr = new StringReader(module.XmlSchema))
                            {
                                DataSet ds = new DataSet();
                                ds.ReadXmlSchema(sr);

                                viewComponentName  = ds.ExtendedProperties["ViewComponent"] as string;
                                agilityCodeRefName = ds.ExtendedProperties["AgilityCodeRefName"] as string;
                            }

                            if (!string.IsNullOrEmpty(viewComponentName))
                            {
                                #region *** VIEW COMPONENTS **
                                var viewComponentFactory = HtmlHelperViewExtensions.GetServiceOrFail <IViewComponentSelector>(AgilityContext.HttpContext);
                                var componentDesc        = viewComponentFactory.SelectComponent(viewComponentName);

                                if (componentDesc == null)
                                {
                                    throw new ApplicationException(string.Format("The view component {0} was not found.", viewComponentName));
                                }

                                MethodInfo method = componentDesc.MethodInfo;


                                if (method == null)
                                {
                                    throw new ApplicationException(string.Format("The component invoke method was not found in the component {0}", viewComponentName));
                                }

                                ParameterInfo[] paramAry = method.GetParameters();
                                if (paramAry.Length > 0)
                                {
                                    ParameterInfo paramInfo = paramAry[0];
                                    Type          paramType = paramInfo.ParameterType;
                                    if (paramType.IsSubclassOf(typeof(AgilityContentItem)) || paramType == typeof(AgilityContentItem))
                                    {
                                        ConstructorInfo ci = paramType.GetConstructor(System.Type.EmptyTypes);

                                        if (ci == null)
                                        {
                                            throw new ApplicationException(string.Format("No default constructor found for type {0}", paramType.Name));
                                        }

                                        AgilityContentItem moduleItem = ci.Invoke(new object[0]) as AgilityContentItem;
                                        moduleItem.DataRow       = drv.Row;
                                        moduleItem.LanguageCode  = AgilityContext.LanguageCode;
                                        moduleItem.ReferenceName = contentReferenceName;
                                        moduleItem.ContentID     = moduleContentID;
                                        moduleItem.VersionID     = moduleVersionID;


                                        try
                                        {
                                            Task <IHtmlContent> task = component.InvokeAsync(viewComponentName, moduleItem);

                                            moduleRender.RenderTask = task;
                                            moduleRender.ContentID  = moduleContentID;
                                        }
                                        catch (Exception ex)
                                        {
                                            moduleRender.PreRenderedContent = new HtmlString($"<p>Error rendering Component {viewComponentName}</p><pre>{ex}</pre>");
                                            moduleRender.ContentID          = moduleContentID;
                                        }
                                    }
                                    else
                                    {
                                        throw new ApplicationException(string.Format("The component invoke method parameter was not of type AgilityContent in the component {0}", viewComponentName));
                                    }
                                    #endregion
                                }
                            }
                            else if (!string.IsNullOrEmpty(agilityCodeRefName))
                            {
                                #region *** Agility Inline Code ***
                                DataView dv = Data.GetContentView(AgilityDynamicCodeFile.REFNAME_AgilityModuleCodeTemplates, AgilityDynamicCodeFile.LANGUAGECODE_CODE);

                                string    filter = string.Format("ReferenceName = '{0}' AND Visible = true", agilityCodeRefName);
                                DataRow[] rows   = dv.Table.Select(filter);
                                if (rows.Length > 0)
                                {
                                    string modulePath =
                                        $"~/Views/{rows[0]["VersionID"]}/DynamicAgilityCode/{AgilityDynamicCodeFile.REFNAME_AgilityModuleCodeTemplates}/{agilityCodeRefName}.cshtml";

                                    AgilityContentItem moduleItem = new AgilityContentItem();
                                    moduleItem.DataRow       = drv.Row;
                                    moduleItem.LanguageCode  = AgilityContext.LanguageCode;
                                    moduleItem.ReferenceName = contentReferenceName;
                                    moduleItem.ContentID     = moduleContentID;
                                    moduleItem.VersionID     = moduleVersionID;
                                    //moduleItem.InlineCodePath = modulePath;

                                    try
                                    {
                                        Task <IHtmlContent> task = component.InvokeAsync("AgilityInlineCode", new { inlineCodePath = modulePath, module = moduleItem });

                                        moduleRender.RenderTask = task;
                                        moduleRender.ContentID  = moduleContentID;
                                    }
                                    catch (Exception ex)
                                    {
                                        moduleRender.PreRenderedContent = new HtmlString($"<p>Error rendering Inline Code</p><pre>{ex}</pre>");
                                        moduleRender.ContentID          = moduleContentID;
                                    }
                                }
                                else
                                {
                                    moduleRender.PreRenderedContent = new HtmlString($"<p>Error rendering Inline Code</p>");
                                    moduleRender.ContentID          = moduleContentID;
                                }
                                #endregion
                            }
                            else if (!string.IsNullOrEmpty(module.ControlPath))
                            {
                                #region *** Control Path - Partial View ***
                                string className = GetClassName(module.ReferenceName ?? module.Name);
                                string typeName  = string.Format("Module_{0}", className);

                                Type paramType = Agility.Web.Utils.FileUtils.GetTypeFromReflection(null, typeName);
                                if (paramType.IsSubclassOf(typeof(AgilityContentItem)) || paramType == typeof(AgilityContentItem))
                                {
                                    ConstructorInfo ci = paramType.GetConstructor(System.Type.EmptyTypes);

                                    if (ci == null)
                                    {
                                        throw new ApplicationException(string.Format("No default constructor found for type {0}", paramType.Name));
                                    }

                                    AgilityContentItem moduleItem = ci.Invoke(new object[0]) as AgilityContentItem;
                                    moduleItem.DataRow       = drv.Row;
                                    moduleItem.LanguageCode  = AgilityContext.LanguageCode;
                                    moduleItem.ReferenceName = contentReferenceName;
                                    moduleItem.ContentID     = moduleContentID;
                                    moduleItem.VersionID     = moduleVersionID;


                                    try
                                    {
                                        Task <IHtmlContent> task = component.InvokeAsync("AgilityPartialView", new { partialViewPath = module.ControlPath, module = moduleItem });

                                        moduleRender.RenderTask = task;
                                        moduleRender.ContentID  = moduleContentID;
                                    }
                                    catch (Exception ex)
                                    {
                                        moduleRender.PreRenderedContent = new HtmlString($"<p>Error rendering Partial View at {module.ControlPath}</p><pre>{ex}</pre>");
                                        moduleRender.ContentID          = moduleContentID;
                                    }
                                }
                                else
                                {
                                    throw new ApplicationException(string.Format("The component invoke method parameter was not of type AgilityContent in the component {0}", viewComponentName));
                                }
                                #endregion
                            }
                            else if (!string.IsNullOrEmpty(module.Markup))
                            {
                                if (module.Markup.StartsWith("@"))
                                {
                                    #region *** Inline Razor Markup ***
                                    AgilityContentItem item = new AgilityContentItem();
                                    item.DataRow       = drv.Row;
                                    item.LanguageCode  = AgilityContext.LanguageCode;
                                    item.ReferenceName = contentReferenceName;
                                    item.ContentID     = moduleContentID;
                                    item.VersionID     = moduleVersionID;
                                    model = item;

                                    string viewPath = string.Format("~/Views/DynamicAgilityModule/MVC/{0}/{1}.cshtml", AgilityContext.CurrentMode, module.ID);

                                    try
                                    {
                                        Task <IHtmlContent> task = component.InvokeAsync("AgilityInlineCode", new { inlineCodePath = viewPath, module = item });

                                        moduleRender.RenderTask = task;
                                        moduleRender.ContentID  = moduleContentID;
                                    }
                                    catch (Exception ex)
                                    {
                                        moduleRender.PreRenderedContent = new HtmlString($"<p>Error rendering Dynamic Agility Module</p><pre>{ex}</pre>");
                                        moduleRender.ContentID          = moduleContentID;
                                    }
                                    #endregion
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            if (Current.Settings.DevelopmentMode)
                            {
                                moduleRender.PreRenderedContent = new HtmlString($"<div>Could not output zone {cs.Name}</div><div>{ex.ToString().Replace("\n", "<br/>")}</div>");
                            }
                            else
                            {
                                moduleRender.PreRenderedContent = new HtmlString($"<!-- Could not output zone {cs.Name} - See web log -->");
                                Agility.Web.Tracing.WebTrace.WriteException(ex);
                            }
                        }
                    }

                    Task <string> sectionTask = Task <string> .Run(() =>
                    {
                        AgilityContext.HttpContext = currentContext;
                        var rendersToOutput        = renders.Where(r => r.RenderTask != null || r.PreRenderedContent != null).ToList();
                        return(AgilityHelpers.RenderModuleHtml(rendersToOutput, cs));
                    });

                    sectionTasks.Add(sectionTask);
                }


                Task <IHtmlContent> retTask = Task.Run <IHtmlContent>(() =>
                {
                    AgilityContext.HttpContext = currentContext;

                    try
                    {
                        Task.WaitAll(sectionTasks.ToArray());
                    } catch { }

                    using (StringWriter htmlStringWriter = new StringWriter())
                    {
                        foreach (var t in sectionTasks)
                        {
                            if (t.IsFaulted)
                            {
                                Agility.Web.Tracing.WebTrace.WriteException(t.Exception, $"Error rendering module in zone {zoneName} - {t.AsyncState}");
                            }
                            else
                            {
                                htmlStringWriter.Write(t.Result);
                            }
                        }

                        TimeSpan ts = DateTime.Now - dtStart;
                        if (ts.TotalSeconds > 1)
                        {
                            string renderTimeMessage = string.Format("Content Zone: {0} - Render Time: {1:F2} seconds.", zoneName, ts.TotalMilliseconds / 1000);
                            Agility.Web.Tracing.WebTrace.WriteVerboseLine(renderTimeMessage);
                            htmlStringWriter.Write(string.Format("<!-- {0} -->", renderTimeMessage));
                        }

                        return(new HtmlString(htmlStringWriter.ToString()));
                    }
                });


                return(retTask);
            }
            catch (Exception ex)
            {
                string errHtml = null;
                string msg     = string.Format("Could not output content zone {0}.", zoneName);
                if (ex is InvalidOperationException && ex.Message.Contains("No route"))
                {
                    msg +=
                        @" This error is usually caused by a missing route in your Global.asax.cs. Ensure the following route is defined after the normal Agility route.\n
routes.MapRoute(""Default"", ""{controller}/{action}/{id}"",\n
    new { controller = """", action = """", id = """" }\n
);";
                }

                if (Current.Settings.DevelopmentMode)
                {
                    errHtml = ex.ToString().Replace("\n", "<br/>");
                }
                else
                {
                    errHtml = msg;
                }

                Agility.Web.Tracing.WebTrace.WriteException(ex, msg);

                return(Task.Run <IHtmlContent>(() => { return new HtmlString(errHtml); }));
            }
        }
Example #11
0
        public async Task <HtmlString> InvokeAsync()
        {
            AgilityContext.HttpContext = HttpContext;

            AgilityPage currentPage = AgilityContext.Page;

            StringBuilder sb = new StringBuilder(Environment.NewLine);

            if (currentPage != null)
            {
                //canonical link
                if (!string.IsNullOrEmpty(AgilityContext.CanonicalLink))
                {
                    sb.AppendFormat("<link rel=\"canonical\" href=\"{0}\" />", AgilityContext.CanonicalLink);
                    sb.Append(Environment.NewLine);
                }

                //set the page specific meta tags
                sb.Append("<meta name=\"description\" content=\"").Append(currentPage.MetaTags).Append("\" />");
                sb.Append(Environment.NewLine);

                if (!string.IsNullOrEmpty(currentPage.MetaKeyWords))
                {
                    sb.Append("<meta name=\"keywords\" content=\"").Append(currentPage.MetaKeyWords).Append("\" />");
                    sb.Append(Environment.NewLine);
                }

                string rawTags = currentPage.MetaTagsRaw;
                if (rawTags == null)
                {
                    rawTags = string.Empty;
                }

                if (!string.IsNullOrEmpty(rawTags))
                {
                    sb.Append(Agility.Web.Util.Url.ResolveTildaUrlsInHtml(rawTags));
                    sb.Append(Environment.NewLine);
                }

                if (!string.IsNullOrEmpty(AgilityContext.TwitterCardSite))
                {
                    if (rawTags.IndexOf("<meta name=\"twitter:site\"", StringComparison.CurrentCultureIgnoreCase) == -1)
                    {
                        string site = AgilityContext.TwitterCardSite;
                        if (!site.StartsWith("@"))
                        {
                            site = string.Format("@{0}", site);
                        }

                        sb.AppendFormat("<meta name=\"twitter:site\" value=\"{0}\" />", site);
                    }

                    string twitterCardType = "summary";
                    if (!string.IsNullOrEmpty(AgilityContext.FeaturedImageUrl))
                    {
                        twitterCardType = "summary_large_image";
                        sb.AppendFormat("<meta name=\"twitter:image:src\" content=\"{0}\" />", AgilityContext.FeaturedImageUrl);
                    }

                    sb.AppendFormat("<meta name=\"twitter:card\" content=\"{0}\" />", twitterCardType);
                    sb.AppendFormat("<meta name=\"twitter:title\" content=\"{0}\" />", currentPage.Title);
                    sb.AppendFormat("<meta name=\"twitter:description\" content=\"{0}\" />", currentPage.MetaTags);
                }

                if (Current.Settings.OutputOpenGraph)
                {
                    sb.AppendFormat("<meta name=\"og:title\" content=\"{0}\" />", currentPage.Title);
                    sb.AppendFormat("<meta name=\"og:description\" content=\"{0}\" />", currentPage.MetaTags);
                    if (!string.IsNullOrEmpty(AgilityContext.FeaturedImageUrl))
                    {
                        sb.AppendFormat("<meta name=\"og:image\" content=\"{0}\" />", AgilityContext.FeaturedImageUrl);
                        sb.Append(Environment.NewLine);
                    }
                }

                //content language
                sb.Append("<meta http-equiv='content-language' content='").Append(currentPage.LanguageCode).Append("'/>");
                sb.Append(Environment.NewLine);

                //default css...
                string globalCss = AgilityContext.Domain.GlobalCss;
                if (!string.IsNullOrEmpty(globalCss))
                {
                    string url = AgilityHelpers.ResolveUrl(string.Format("~/{0}/global.css",
                                                                         Agility.Web.HttpModules.AgilityHttpModule.ECMS_EDITOR_CSS_KEY));
                    sb.AppendFormat("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />", url);
                }


                //set the custom agility meta tags

                sb.Append("<meta name=\"generator\" content=\"Agility CMS\" />");
                sb.Append(Environment.NewLine);

                sb.AppendFormat("<meta name=\"agility_timestamp\" content=\"{0:yyyy/MM/dd hh:mm:ss tt}\" />", DateTime.Now);

                sb.AppendFormat("<meta name=\"agility_attributes\" content=\"Mode={0}, IsPreview={1}, Language={2}, Machine={3}, CustomOutputCache={4}\" />",
                                AgilityContext.CurrentMode,
                                AgilityContext.IsPreview,
                                AgilityContext.LanguageCode,
                                Environment.MachineName,
                                AgilityCache.UseAgilityOutputCache);
                sb.Append(Environment.NewLine);
            }

            //add the StatusPanelEmitter if in preview mode, development mode, or edit in place
            if (AgilityContext.IsPreview ||
                Current.Settings.DevelopmentMode ||
                AgilityContext.IsTemplatePreview)
            {
                sb.Append(StatusPanelEmitter.GetStatusPanelCssOnly());
            }


            return(new HtmlString(sb.ToString()));
        }
Example #12
0
        /// <summary>
        /// Output the bottom scripts defined in the Page and Globally, as well as the Form Builder scripts if the Form module was used on this page.
        /// </summary>
        /// <param name="helper"></param>
        public static HtmlString RenderAgilityBottomScripts(this IHtmlHelper helper)
        {
            AgilityPage currentPage = AgilityContext.Page;

            if (currentPage == null)
            {
                return(new HtmlString(""));
            }

            StringBuilder sb = new StringBuilder(Environment.NewLine);

            string scriptTopGlobal;
            string scriptBottomGlobal;


            string scriptBottomPage = null;

            //add the Javascript tracking stuff
            if (currentPage.IncludeInStatsTracking)
            {
                //global script
                if (!string.IsNullOrEmpty(AgilityContext.Domain.StatsTrackingScript))
                {
                    scriptTopGlobal    = AgilityContext.Domain.StatsTrackingScript;
                    scriptBottomGlobal = string.Empty;

                    if (scriptTopGlobal.IndexOf(GLOBAL_SCRIPT_SEPARATOR) != -1)
                    {
                        scriptBottomGlobal = scriptTopGlobal.Substring(scriptTopGlobal.IndexOf(GLOBAL_SCRIPT_SEPARATOR) + GLOBAL_SCRIPT_SEPARATOR.Length);
                        scriptTopGlobal    = scriptTopGlobal.Substring(0, scriptTopGlobal.IndexOf(GLOBAL_SCRIPT_SEPARATOR));
                    }

                    if (!string.IsNullOrEmpty(scriptBottomGlobal))
                    {
                        sb.Append(scriptBottomGlobal);
                        sb.Append(Environment.NewLine);
                    }
                }
            }

            string scriptTopPage = null;

            //custom script for this page
            if (!string.IsNullOrEmpty(currentPage.CustomAnalyticsScript))
            {
                scriptTopPage = currentPage.CustomAnalyticsScript;

                if (scriptTopPage.IndexOf(GLOBAL_SCRIPT_SEPARATOR) != -1)
                {
                    scriptBottomPage = scriptTopPage.Substring(scriptTopPage.IndexOf(GLOBAL_SCRIPT_SEPARATOR) + GLOBAL_SCRIPT_SEPARATOR.Length);
                    scriptTopPage    = scriptTopPage.Substring(0, scriptTopPage.IndexOf(GLOBAL_SCRIPT_SEPARATOR));
                }

                if (!string.IsNullOrEmpty(scriptBottomPage))
                {
                    sb.Append(scriptBottomPage);
                    sb.Append(Environment.NewLine);
                }
            }

            return(new HtmlString(sb.ToString()));
        }
Example #13
0
        internal static bool IsStagingItemOutOfDate(object existingItem)
        {
            if (existingItem == null)
            {
                return(true);
            }
            AgilityContent         existingItem_Content = existingItem as AgilityContent;
            AgilitySitemap         existingItem_Sitemap = existingItem as AgilitySitemap;
            AgilityPage            existingItem_Page    = existingItem as AgilityPage;
            AgilityModule          existingItem_Module  = existingItem as AgilityModule;
            AgilityAssetMediaGroup existingItem_Gallery = existingItem as AgilityAssetMediaGroup;

            if (existingItem_Content != null)
            {
                //CONTENT
                int versionID             = 0;
                int maxVersionIDInDataSet = 0;
                if (existingItem_Content.DataSet != null)
                {
                    if (existingItem_Content.DataSet.ExtendedProperties.ContainsKey("MaxVersionID"))
                    {
                        int.TryParse(string.Format("{0}", existingItem_Content.DataSet.ExtendedProperties["MaxVersionID"]), out maxVersionIDInDataSet);
                    }

                    DataTable dt = existingItem_Content.DataSet.Tables["ContentItems"];
                    if (dt != null && dt.Columns["VersionID"] != null)
                    {
                        try
                        {
                            object maxObj = dt.Compute("max(VersionID)", "");
                            if (!int.TryParse($"{maxObj}", out versionID))
                            {
                                versionID = -1;
                            }
                        } catch (Exception ex)
                        {
                            throw ex;
                        }
                    }


                    if (maxVersionIDInDataSet > versionID)
                    {
                        versionID = maxVersionIDInDataSet;
                    }
                }


                int latestVersionID = CheckContentIndex(versionID, existingItem_Content.ReferenceName, existingItem_Content.LanguageCode);
                if (latestVersionID > 0)
                {
                    if (existingItem_Content.DataSet != null)
                    {
                        existingItem_Content.DataSet.ExtendedProperties["MaxVersionID"] = latestVersionID;
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (existingItem_Page != null)
            {
                //PAGE
                return(CheckPageIndex(existingItem_Page.ZVersionID, existingItem_Page.ID, existingItem_Page.LanguageCode));
            }
            else if (existingItem_Module != null)
            {
                //MODULE DEF
                return(CheckContentDefinitionIndex(existingItem_Module.ID, existingItem_Module.LastAccessDate));
            }
            else if (existingItem_Sitemap != null)
            {
                //SITEMAP
                return(CheckPageIndex(existingItem_Sitemap.XMaxPageVersionID, -1, existingItem_Sitemap.LanguageCode));
            }
            else if (existingItem_Gallery != null)
            {
                //MEDIA GROUPING/GALLERY

                DateTime dtModifiedOn = existingItem_Gallery.ModifiedOn;

                if (existingItem_Gallery.Media != null && existingItem_Gallery.Media.Length > 0)
                {
                    //check for the most recent item..

                    DateTime dtItem = existingItem_Gallery.Media.Max(d => d.ModifiedOn);
                    if (dtItem > dtModifiedOn)
                    {
                        dtModifiedOn = dtItem;
                    }
                }


                return(CheckMediaGalleryIndex(existingItem_Gallery.ID, dtModifiedOn));
            }



            return(true);
        }
Example #14
0
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            AgilityContext.HttpContext = httpContext;
//TODO: handle malicious request throttling (read)

            //ErrorTraceElement elem = Current.Settings.Trace.ErrorTraceTypes.FindDangerousRequestMatch();

            ////if the TraceElement exists and this path IS NOT the specified throttleRedirect
            //if (elem != null && !string.Equals(HttpContext.Current.Request.Path, elem.RequestThrottleRedirect, StringComparison.OrdinalIgnoreCase))
            //{
            //    bool throttle = AgilityHttpModule.HandleDangerousRequest(elem, HttpContext.Current.Request, HttpContext.Current.Response);

            //    if (throttle) return false;
            //}

            string controllerName = values["Controller"] as string;

            if (!string.Equals(controllerName, "Agility"))
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(httpContext.Request.Query["lang"]))
            {
                //if the languagecode is in the URL, redirect...
                return(true);
            }

            string domain       = httpContext.Request.Host.Value;
            string sitemapPath  = values["sitemapPath"] as string;
            string languageCode = values["languageCode"] as string;

            //ECMS_DOCUMENTS_KEY = "ecm
            //ECMS_DOCUMENTS_KEY2 = "ec
            //ECMS_RSS_KEY = "ecmsrss.a
            //ECMS_ERRORS_KEY = "ecmser
            //ECMS_EDITOR_CSS_KEY = "ec

            if (!string.IsNullOrEmpty(sitemapPath) &&
                (sitemapPath.IndexOf(AgilityHttpModule.ECMS_DOCUMENTS_KEY2, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                 sitemapPath.IndexOf(AgilityHttpModule.ECMS_RSS_KEY, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                 sitemapPath.IndexOf(AgilityHttpModule.ECMS_ERRORS_KEY, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                 sitemapPath.IndexOf(AgilityHttpModule.ECMS_EDITOR_CSS_KEY, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                 sitemapPath.IndexOf(AgilityHttpModule.DynamicCodePrepend, StringComparison.CurrentCultureIgnoreCase) != -1 ||
                 sitemapPath.IndexOf("TemplatePreview/", StringComparison.CurrentCultureIgnoreCase) >= 0 ||
                 (!string.IsNullOrEmpty(httpContext.Request.Query["agilitypreviewkey"]))
                )
                )
            {
                return(true);
            }

            try
            {
                //test to see if the language code is in the URL...
                string pathWithOutSlash = sitemapPath;
                if (pathWithOutSlash == null)
                {
                    pathWithOutSlash = string.Empty;
                }
                if (pathWithOutSlash.StartsWith("~/"))
                {
                    pathWithOutSlash = pathWithOutSlash.Substring(2);
                }
                if (pathWithOutSlash.StartsWith("/"))
                {
                    pathWithOutSlash = pathWithOutSlash.Substring(1);
                }

                string languageCodeTest = null;

                //strip out the language from the url (first folder path)
                int index = pathWithOutSlash.IndexOf("/");
                if (index > 0)
                {
                    languageCodeTest = pathWithOutSlash.Substring(0, index);
                    pathWithOutSlash = pathWithOutSlash.Substring(index + 1);
                }
                else
                {
                    languageCodeTest = pathWithOutSlash;
                    pathWithOutSlash = string.Empty;
                }

                AgilityContentServer.AgilityDomainConfiguration config = BaseCache.GetDomainConfiguration(AgilityContext.WebsiteName);
                //if (config == null) throw new Exception("Could not access the Domain Configuration.");

                if (config != null && config.Languages != null)
                {
                    var lang = config.Languages.FirstOrDefault(l => string.Equals(l.LanguageCode, languageCodeTest, StringComparison.CurrentCultureIgnoreCase));
                    if (lang != null)
                    {
                        //found the language code in the URL, switch up the values...
                        sitemapPath  = pathWithOutSlash;
                        languageCode = languageCodeTest;
                    }
                }
            }
            catch (Exception ex)
            {
                Agility.Web.Tracing.WebTrace.WriteException(ex);
            }



            if (HttpModules.AgilityHttpModule.HandleChannelsAndRedirects(ref sitemapPath, languageCode))
            {
                //set a variable that says we can redirect now...
                httpContext.Items["Agility.Web.RequestPreviouslyHandledInRouteConstraint"] = true;
                return(true);
            }

            AgilityPage agilityPage = Agility.Web.Data.GetPage(sitemapPath, languageCode);

            return(agilityPage != null || AgilityContext.IsResponseEnded);
        }