/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Text.RegularExpressions;
using Everest.Library;
using Everest.Library.ExtensionMethod;
using Everest.CmsServices.Models;
using Everest.CmsServices.Exceptions;
using Everest.Library.Providers.Caching;
using Everest.CmsServices.Services;
using System.IO;
using Everest.Library.Web;
using Everest.CmsServices.Web;
namespace Everest.CmsServices.MvcHelper{
/// <summary>
///
/// </summary>
public static class UrlHelperExtensions
{
#region RequestContext Mock
private class ContentMockHttpContenxt : HttpContextWrapper
{
private HttpRequestBase requestBase;
public ContentMockHttpContenxt(HttpContext httpContext, HttpRequestBase requestBase)
: base(httpContext)
{
this.requestBase = requestBase;
}
public override HttpRequestBase Request
{
get
{
return this.requestBase;
}
}
}
private class ContentMockHttpRequest : HttpRequestWrapper
{
private string appRelativeCurrentExecutionFilePath;
private string pathInfo;
public ContentMockHttpRequest(HttpRequest httpRequest, string appRelativeCurrentExecutionFilePath, string pathInfo)
: base(httpRequest)
{
this.appRelativeCurrentExecutionFilePath = appRelativeCurrentExecutionFilePath;
this.pathInfo = pathInfo;
}
public override string AppRelativeCurrentExecutionFilePath
{
get
{
return this.appRelativeCurrentExecutionFilePath;
}
}
public override string PathInfo
{
get
{
return this.pathInfo;
}
}
}
#endregion
#region Generate cms page Url
#region PageUrl
/// <summary>
/// genereate the page URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="pageVirtualPath">The page virtual path.</param>
/// <returns></returns>
public static string PageUrl(this UrlHelper urlHelper, string pageVirtualPath)
{
return PageUrl(urlHelper, pageVirtualPath, null);
}
/// <summary>
/// genereate the page URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="pageVirtualPath">The page virtual path.</param>
/// <param name="routeValues">The route values.</param>
/// <returns></returns>
public static string PageUrl(this UrlHelper urlHelper, string pageVirtualPath, object routeValues)
{
return PageUrl(urlHelper, pageVirtualPath, routeValues, false);
}
/// <summary>
/// genereate the page URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="pageVirtualPath">The page virtual path.</param>
/// <param name="useDefaultRouteValues">if set to <c>true</c> [use default route values].</param>
/// <returns></returns>
public static string PageUrl(this UrlHelper urlHelper, string pageVirtualPath, bool useDefaultRouteValues)
{
return PageUrl(urlHelper, pageVirtualPath, null, false);
}
/// <summary>
/// Pages the URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="application">The application.</param>
/// <param name="pageName">Name of the page.</param>
/// <param name="routeValues">The route values.</param>
/// <returns></returns>
//[Obsolete("")]
//public static string PageUrl(this UrlHelper urlHelper, string application, string pageName, object routeValues)
//{
// return PageUrl(urlHelper, application, pageName, routeValues, false);
//}
/// <summary>
/// genereate the content URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="pageVirtualPath">The page virtual path. news; news/detail</param>
/// <param name="routeValues">The route values.</param>
/// <param name="useDefaultRouteValues">if set to <c>true</c> [use default route values].</param>
/// <returns></returns>
internal static string PageUrl(UrlHelper urlHelper, string pageVirtualPath, object routeValues, bool useDefaultRouteValues)
{
//if (string.IsNullOrEmpty(applicationName))
//{
// applicationName = urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application.ApplicationName;
//}
aspnet_Applications application = urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application;
IEverestCmsDataContext dataContext = urlHelper.RequestContext.HttpContext.GetCmsContext().DataContext;
Cms_Page cms_page = CachedData.GetPageByVirtualPath(application.ApplicationName, pageVirtualPath.ToLower());
if (cms_page == null)
{
Everest.Library.HealthMonitor.HealthMonitoringLogging.LogError(new Everest.CmsServices.Exceptions.PageNotFoundException(pageVirtualPath));
return string.Empty;
}
RouteValueDictionary contentRouteValues = routeValues as RouteValueDictionary;
if (contentRouteValues == null)
{
contentRouteValues = new RouteValueDictionary(routeValues);
}
if (useDefaultRouteValues == true)
{
contentRouteValues = cms_page.Route.Defaults;
}
string pageUrl = GenerateContextPageUrl(urlHelper, cms_page, contentRouteValues);
return pageUrl;
}
/// <summary>
/// Constructs the content URL.
/// Will be used by generate paging url.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="applicationName">Name of the application.</param>
/// <param name="cms_page">The cms_page.</param>
/// <param name="contentRouteValues">The content route values.</param>
/// <returns></returns>
internal static string GenerateContextPageUrl(this UrlHelper urlHelper, Cms_Page cms_page, RouteValueDictionary contentRouteValues)
{
var applicationName = urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application.ApplicationName;
var visitType = ((KoobooHttpRequestWrapper)urlHelper.RequestContext.HttpContext.Request).VisitType;
return GeneratePageUrl(urlHelper, applicationName, cms_page, contentRouteValues, visitType);
}
private static string GeneratePageUrl(UrlHelper urlHelper, string applicationName, Cms_Page cms_page, RouteValueDictionary contentRouteValues, CmsVisitType visitType)
{
//when generate the paging url, must be specify the {pageIndex} parameter on page url.
var virtualPath = cms_page.Route.GetVirtualPath(urlHelper.RequestContext, contentRouteValues);
if (virtualPath == null)
{
throw new InvalidPageRoutingException(cms_page.VirtualPath);
}
string contentUrl = HttpUtility.UrlDecode(virtualPath.VirtualPath);
return PrivateGenerateUrl(urlHelper, applicationName, cms_page.VirtualPath, contentUrl, visitType);
}
/// <summary>
/// Generates the page URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="pageVirtualPath">The page virtual path.</param>
/// <param name="contentUrl">The content URL.</param>
/// <returns></returns>
internal static string GenerateContextPageUrl(this UrlHelper urlHelper, string pageVirtualPath, string contentUrl)
{
aspnet_Applications application = urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application;
var visitType = ((KoobooHttpRequestWrapper)urlHelper.RequestContext.HttpContext.Request).VisitType;
return PrivateGenerateUrl(urlHelper, application.ApplicationName, pageVirtualPath, contentUrl, visitType);
}
/// <summary>
/// Privates the generate URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="applicationName">Name of the application.</param>
/// <param name="pageVirtualPath">The page virtual path.</param>
/// <param name="contentUrl">The content URL.</param>
/// <param name="visitType">Type of the visit.</param>
/// <returns></returns>
private static string PrivateGenerateUrl(UrlHelper urlHelper, string applicationName, string pageVirtualPath, string contentUrl, CmsVisitType visitType)
{
string absolutePath = "";
if (string.IsNullOrEmpty(applicationName))
{
throw new ArgumentNullException("applicationName");
}
var pageUrl = contentUrl;
if (!string.IsNullOrEmpty(pageVirtualPath))
{
var page = CachedData.GetPageByVirtualPath(applicationName, pageVirtualPath.ToLower());
if (page == null)
{
Everest.Library.HealthMonitor.HealthMonitoringLogging.LogError(new Everest.CmsServices.Exceptions.PageNotFoundException(pageVirtualPath));
return string.Empty;
}
if (string.IsNullOrEmpty(contentUrl))
{
pageUrl = page.VirtualPath;
}
else
{
pageUrl = page.VirtualPath + "/" + contentUrl;
}
}
if (visitType == Everest.CmsServices.Web.CmsVisitType.Host || visitType == CmsVisitType.HostNVirtual)
{
absolutePath = urlHelper.RouteUrl("CommonInDNSHost", new { pageUrl = pageUrl });
if (visitType == CmsVisitType.HostNVirtual)
{
if (urlHelper.RequestContext.HttpContext.Request.ApplicationPath != "/")
{
absolutePath = absolutePath.Replace(urlHelper.RequestContext.HttpContext.Request.ApplicationPath, "");
}
var app = CachedData.GetApplication(applicationName);
absolutePath = "/" + app.VirtualPath + absolutePath;
if (urlHelper.RequestContext.HttpContext.Request.ApplicationPath != "/")
{
absolutePath = urlHelper.RequestContext.HttpContext.Request.ApplicationPath + absolutePath;
}
}
}
else
{
absolutePath = urlHelper.RouteUrl("Common", new { application = applicationName, pageUrl = pageUrl });
}
return absolutePath;
}
#endregion
#region Dynamic Content Url
/// <summary>
/// Generate Dynamic page URL
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="textContentId">The text content id.</param>
/// <returns></returns>
public static string DynamicPageUrlForText(this UrlHelper urlHelper, int textContentId)
{
return DynamicPageUrlForText(urlHelper, textContentId, null);
}
/// <summary>
/// Dynamics the page URL for text.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="textContentId">The text content id.</param>
/// <param name="dynamicLinkingOrder">The dynamic linking order. Query the data rule dynamic linking order.</param>
/// <returns></returns>
public static string DynamicPageUrlForText(this UrlHelper urlHelper, int textContentId, int? dynamicLinkingOrder)
{
return DynamicPageUrlForText(urlHelper, textContentId, null, dynamicLinkingOrder);
}
/// <summary>
/// Gets the text content URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="textContentId">The text content id.</param>
/// <param name="values">The values.</param>
/// <param name="dynamicLinkingOrder">The dynamic linking order.</param>
/// <returns></returns>
public static string DynamicPageUrlForText(this UrlHelper urlHelper, int textContentId, object values, int? dynamicLinkingOrder)
{
IEverestCmsDataContext dataContext = urlHelper.RequestContext.HttpContext.GetCmsContext().DataContext;
var folderId = dataContext.QueryContent(textContentId).Select(c => c.Cms_Folder.FolderId).First();
return DynamicPageUrlForText(urlHelper, dataContext, values, urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application.ApplicationName, folderId, textContentId, dynamicLinkingOrder);
}
/// <summary>
/// match the data rule parameter
/// </summary>
static Regex urlParameters = new Regex(@"{(?<TextContentId>[\w|\d|_]+)}", RegexOptions.Compiled | RegexOptions.IgnoreCase);
/// <summary>
/// Gets the text content URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="values">The values.</param>
/// <param name="applicationName">Name of the application.</param>
/// <param name="dataContext">The data context.</param>
/// <param name="folderId">The folder id.</param>
/// <param name="contentId">The content id.</param>
/// <returns></returns>
private static string DynamicPageUrlForText(UrlHelper urlHelper, IEverestCmsDataContext dataContext, object values, string applicationName, int folderId, int textContentId, int? dynamicLinkingOrder)
{
string pageUrl = "";
var localizedPage = GetDynamicPage(dataContext, folderId, applicationName, dynamicLinkingOrder);
if (localizedPage != null)
{
//get the first parameter , default use to transfer the binary content id.
//Match match = urlParameters.Match(localizedPage.Url);
RouteValueDictionary contentRouteValues = new RouteValueDictionary(values);
contentRouteValues.Add("ContentId", textContentId);
pageUrl = GenerateContextPageUrl(urlHelper, localizedPage, contentRouteValues);
}
return pageUrl;
}
/// <summary>
/// Gets the dynamic page.
/// </summary>
/// <param name="dataContext">The data context.</param>
/// <param name="folderId">The folder id.</param>
/// <param name="applicationName">Name of the application.</param>
/// <param name="dynamicLinkingOrder">The dynamic linking order.</param>
/// <returns></returns>
private static Cms_Page GetDynamicPage(IEverestCmsDataContext dataContext, int folderId, string applicationName, int? dynamicLinkingOrder)
{
string cacheKey = string.Format("__DynamicPage_FolderId:{0}_ApplicationName:{1}_DynamicLinkingOrder:{2}", folderId, applicationName, dynamicLinkingOrder);
Cms_Page localizedPage = CacheManager.Get(CachedData.Page, cacheKey) as Cms_Page;
if (localizedPage == null)
{
var page = dataContext.QueryPagesByDataRule(folderId, DataRuleValueType.Object, applicationName, dynamicLinkingOrder).Select(dr => dr.Cms_Page).FirstOrDefault();
if (page != null)
{
localizedPage = CachedData.GetPage(applicationName, page.LoweredPageName);
CacheManager.Add(CachedData.Page, cacheKey, localizedPage, CacheItemPriority.Normal, null, CachedData.DefaultExpirations);
}
}
return localizedPage;
}
/// <summary>
///
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="binaryContentId">The binary content id.</param>
/// <returns></returns>
public static string DynamicPageUrlForBinary(this UrlHelper urlHelper, string binaryContentId)
{
return DynamicPageUrlForBinary(urlHelper, int.Parse(binaryContentId));
}
/// <summary>
/// Gets the content of the text URL for binary.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="binaryContentId">The binary content id.</param>
/// <returns></returns>
public static string DynamicPageUrlForBinary(this UrlHelper urlHelper, int binaryContentId)
{
return DynamicPageUrlForBinary(urlHelper, binaryContentId, null, null);
}
/// <summary>
/// Dynamics the page URL for binary.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="binaryContentId">The binary content id.</param>
/// <param name="dynamicLinkingOrder">The dynamic linking order.</param>
/// <returns></returns>
public static string DynamicPageUrlForBinary(this UrlHelper urlHelper, int binaryContentId, int? dynamicLinkingOrder)
{
return DynamicPageUrlForBinary(urlHelper, binaryContentId, null, dynamicLinkingOrder);
}
/// <summary>
///
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="binaryContentId">The binary content id.</param>
/// <param name="values">The values.</param>
/// <returns></returns>
public static string DynamicPageUrlForBinary(this UrlHelper urlHelper, int binaryContentId, object values, int? dynamicLinkingOrder)
{
string pageUrl = string.Empty;
aspnet_Applications application = urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application;
IEverestCmsDataContext dataContext = urlHelper.RequestContext.HttpContext.GetCmsContext().DataContext;
var content = dataContext.QueryContentFiles(binaryContentId).Select(bc => new
{
bc.TextContent.ContentId,
bc.TextContent.Cms_Folder.FolderId
}).FirstOrDefault();
if (content != null)
{
int folderId = content.FolderId;
int contentId = content.ContentId;
pageUrl = DynamicPageUrlForText(urlHelper, dataContext, values, application.ApplicationName, folderId, contentId, dynamicLinkingOrder);
}
return pageUrl;
}
#endregion
#endregion
#region CmsPageRouteValues
/// <summary>
/// Parses the CMS page route values.
/// </summary>
/// <param name="routeData">The route data.</param>
/// <param name="context">The context.</param>
/// <param name="routeValues">The route values.</param>
/// <param name="cms_Page">The CMS_ page.</param>
/// <returns></returns>
internal static CmsPageRouteData ParseCmsPageRouteValues(this RouteData routeData, HttpContext context, RouteValueDictionary routeValues, Cms_Page cms_Page, string parameterUrl)
{
context.Request.QueryString.SetReadOnly(false);
HttpContextBase mockContext = new ContentMockHttpContenxt(context, new ContentMockHttpRequest(context.Request, "~/" + parameterUrl, ""));
RouteData pageRouteData = cms_Page.Route.GetRouteData(mockContext);
if (pageRouteData != null)
{
foreach (var item in pageRouteData.Values)
{
if (context.Request.QueryString[item.Key] == null && item.Value != null)
{
context.Request.QueryString.Add(item.Key, item.Value.ToString());
}
if (!routeData.Values.ContainsKey(item.Key))
{
routeData.Values.Add(item.Key, item.Value);
}
}
}
context.Request.QueryString.SetReadOnly(true);
return new CmsPageRouteData(pageRouteData, context.Request.QueryString);
}
#endregion
#region GetBinaryResource
/// <summary>
/// Gets the binary resource file URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="relativeFilePath">The relative file path. e.g.: javascript/jquery.js</param>
/// <returns></returns>
public static string GetResourceFileUrl(this UrlHelper urlHelper, string relativeFilePath)
{
if (StringExtensions.IsNullOrEmptyTrim(relativeFilePath))
{
return string.Empty;
}
if (relativeFilePath.StartsWith("~/"))
{
relativeFilePath = relativeFilePath.Substring(2);
}
if (relativeFilePath.StartsWith("/"))
{
relativeFilePath = relativeFilePath.Substring(1);
}
var cmsContext = urlHelper.RequestContext.HttpContext.GetCmsContext();
var binaryResourceRootPath = TemplateFileManager.GetAbsoluteTemplateFolderPath(cmsContext.Cms_Application.ApplicationName, FolderType.BinaryResource);
var binaryResourceFilePath = Path.Combine(binaryResourceRootPath, relativeFilePath);
return urlHelper.ResolveUrl(UrlConvertor.AbsolutePathToRelativeUrl(binaryResourceFilePath));
}
/// <summary>
/// Gets the theme file URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="themeFileName">Name of the theme file.</param>
/// <returns></returns>
public static string GetThemeFileUrl(this UrlHelper urlHelper, string themeFileName)
{
var cmsContext = urlHelper.RequestContext.HttpContext.GetCmsContext();
if (string.IsNullOrEmpty(cmsContext.Cms_Application.Theme))
{
return themeFileName;
}
var themeFilePath = Path.Combine(TemplateFileManager.GetThemePath(cmsContext.Cms_Application.Theme), themeFileName);
return urlHelper.ResolveUrl(UrlConvertor.AbsolutePathToRelativeUrl(themeFilePath));
}
#endregion
#region Resize Image
/// <summary>
/// Resizes the image URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="imgUrl">The img URL.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
public static string ResizeImageUrl(this UrlHelper urlHelper, string imgUrl, int width, int height)
{
return ResizeImageUrl(urlHelper, imgUrl, width, height, true);
}
/// <summary>
/// Resizes the image URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="imgUrl">The img URL.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="cache">if set to <c>true</c> [cache].</param>
/// <returns></returns>
public static string ResizeImageUrl(this UrlHelper urlHelper, string imgUrl, int width, int height, bool cache)
{
return urlHelper.RouteUrl("Kooboo", new { Controller = "WebResource", Action = "ResizeImage", url = HttpUtility.UrlEncode(imgUrl), width = width, height = height, cache = cache });
}
#endregion
#region Get Application Url
/// <summary>
/// get the Applications URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="application">The application.</param>
/// <returns></returns>
public static string ApplicationUrl(this UrlHelper urlHelper, string application)
{
var app = CachedData.GetApplication(application);
var url = PrivateGenerateUrl(urlHelper, application, "", "", app.VisitType);
url = CombineHostName(app, url);
return url;
}
internal static string CombineHostName(aspnet_Applications app, string url)
{
if (!string.IsNullOrEmpty(app.HostName))
{
var hosts = app.HostName.Split(',');
Uri hostUri = new Uri("http://" + hosts[0]);
url = new Uri(hostUri, url).AbsoluteUri;
}
if (url.EndsWith("/"))
{
url = url.Substring(0, url.Length - 1);
}
return url;
}
/// <summary>
/// The application page URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="application">The application.</param>
/// <param name="pageVirtualPath">The page virtual path. news; news/detail</param>
/// <param name="routeValues">The route values.</param>
/// <returns></returns>
public static string ApplicationPageUrl(this UrlHelper urlHelper, string application, string pageVirtualPath, object routeValues)
{
var app = CachedData.GetApplication(application);
Cms_Page cms_page = CachedData.GetPageByVirtualPath(application, pageVirtualPath);
RouteValueDictionary contentRouteValues = new RouteValueDictionary(routeValues);
var url = GeneratePageUrl(urlHelper, application, cms_page, contentRouteValues, app.VisitType);
url = CombineHostName(app, url);
return url;
}
#endregion
#region Rss
/// <summary>
/// Generates the rss URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="rssChannelName">Name of the RSS channel.</param>
/// <returns></returns>
public static string RssUrl(this UrlHelper urlHelper, string rssChannelName)
{
return urlHelper.RssUrl(urlHelper.RequestContext.HttpContext.GetCmsContext().Cms_Application.ApplicationName, rssChannelName, ((KoobooHttpRequestWrapper)urlHelper.RequestContext.HttpContext.Request).VisitType);
}
/// <summary>
/// Generates the rss URL.
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <param name="application">The application.</param>
/// <param name="rssChannelName">Name of the RSS channel.</param>
/// <returns></returns>
public static string RssUrl(this UrlHelper urlHelper, string application, string rssChannelName, CmsVisitType visitType)
{
RouteValueDictionary routeValues = new RouteValueDictionary();
routeValues.Add("rssName", rssChannelName);
if (visitType != Everest.CmsServices.Web.CmsVisitType.Host && visitType != CmsVisitType.HostNVirtual)
{
routeValues.Add("application", application);
}
return urlHelper.RouteUrl("rss", routeValues);
}
#endregion
}
}
|