/*
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.Web;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Routing;
using Everest.CmsServices.DataRule;
using Everest.CmsServices.Extension;
using Everest.CmsServices.Extension.PagePlugin;
using Everest.CmsServices.Models;
using Everest.CmsServices.MvcHelper;
using Everest.CmsServices.Providers;
using Everest.CmsServices.Services;
using Everest.Library;
using Everest.Library.Data;
using Everest.Library.Data.Entity;
using Everest.Library.ExtensionMethod;
using Everest.Library.Mvc;
using Everest.Library.Mvc.View;
using Everest.Library.Providers.Caching;
using Everest.Library.Security;
using Everest.CmsServices.Exceptions;
namespace Everest.CmsServices.Controllers{
/// <summary>
///
/// </summary>
[ValidateInput(false)]
public class CommonController : EverestControllerBase
{
#region ctor.
IContentProvider contentProvider;
/// <summary>
/// Initializes a new instance of the <see cref="CommonController"/> class.
/// </summary>
/// <param name="contentProvider">The content provider.</param>
public CommonController(IContentProvider contentProvider)
{
this.contentProvider = contentProvider;
this.ActionResultHelper = new CmsActionResultHelper(this);
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the application.
/// </summary>
/// <value>The application.</value>
public aspnet_Applications Application
{
get
{
return this.CmsContext.Cms_Application;
}
protected set
{
this.CmsContext.Cms_Application = value;
}
}
/// <summary>
/// Gets or sets the CMS_ page.
/// </summary>
/// <value>The CMS_ page.</value>
public Cms_Page Cms_Page
{
get
{
return this.CmsContext.Cms_Page;
}
protected set
{
this.CmsContext.Cms_Page = value;
}
}
/// <summary>
/// Gets or sets the data context.
/// </summary>
/// <value>The data context.</value>
public IEverestCmsDataContext DataContext
{
get
{
return this.CmsContext.DataContext;
}
}
public IContentProvider ContentProvider
{
get
{
return this.CmsContext.ContentProvider;
}
set
{
this.CmsContext.ContentProvider = value;
}
}
public CmsContext CmsContext
{
get
{
return this.ControllerContext.HttpContext.GetCmsContext();
}
}
#endregion
#region Cms Page
public virtual ActionResult Execute()
{
//string applicationName = EverestContext.GetContext().CmsApplicationName; //this.RouteData.Values["applicationName"].ToString().ToLower();
Application = ((Everest.CmsServices.Web.KoobooHttpRequestWrapper)Request).CmsApplication;
if (Application == null)
{
return ApplicationNotFound();
}
var applicationName = Application.ApplicationName;
PrepareContext();
ActionResult actionResult = null;
if (!CmsContext.IsDesignMode)
{
//Authorize permission
CmsRoleAuthorizer roleAuthorizer = UnityManager.Resolve<CmsRoleAuthorizer>();
if (!roleAuthorizer.IsAuthorized(Application.ApplicationName, this.Cms_Page.Denies, this.Cms_Page.Allows, User))
{
throw new UnauthorizedException(Resources.UnauthorizedAccess);
}
//get controller modules
IEnumerable<IControllerPlugin> controllerModules = GetPagePlugins();
actionResult = ExecutePluginsPreAction(controllerModules);
//default logic
if (actionResult == null)
{
//query the data by the data rule
DataRuleEvaluator.Evaluate(CmsContext.DataRuleContext, CachedData.GetDataRuleByPage(this.Cms_Page.PageId));
actionResult = PageViewResult(applicationName);
actionResult = ExecutePluginPostAction(controllerModules, actionResult);
}
}
else
{
actionResult = PageViewResult(applicationName);
}
return actionResult;
}
protected virtual ActionResult PageViewResult(string applicationName)
{
var pageTemplate = CachedData.GetPageTemplate(applicationName, CachedData.GetPageTemplateByPage(Cms_Page.UUID).OriginalUUID);
//get page template file.
string viewFile = pageTemplate.GetVirtualPath();
ActionResult actionResult = ViewPath(viewFile, "", null);
return actionResult;
}
protected virtual IEnumerable<IControllerPlugin> GetPagePlugins()
{
string cacheKey = Cms_Page.EntityKey.GetEntityKey();
List<string> controllerModuleTypes = CacheManager.Get(CachedData.DataRule, cacheKey) as List<string>;
if (controllerModuleTypes == null)
{
var contentTemplatePlugins = DataContext.Cms_ContentTemplateInPageHolder
.Where(p => p.Cms_Page.PageId == Cms_Page.PageId && p.Cms_ContentTemplate != null)
.Select(p => p.Cms_ContentTemplate.Cms_Plugin);
controllerModuleTypes = new List<string>();
foreach (var plugins in contentTemplatePlugins)
{
controllerModuleTypes.AddRange(plugins.Select(p => p.PluginType));
}
//Cms_Page.Cms_Plugin.Load();
//the Cms_Plugin loaded by Page CacheData.
controllerModuleTypes.AddRange(CachedData.GetPluginsByPage(Cms_Page.UUID).Select(p => p.PluginType));
CacheManager.Add(CachedData.DataRule, cacheKey,
controllerModuleTypes, CacheItemPriority.Normal, null, CachedData.DefaultExpirations);
}
IPluginResolver<IControllerPlugin> pluginResolver = AssemblyFileManager.PagePluginResolver;
var controllerModules = pluginResolver.Resolve(controllerModuleTypes);
return controllerModules;
}
protected virtual void PrepareContext()
{
this.ContentProvider = contentProvider;
InitPage();
CmsContext.DataRuleContext = new DataRuleContext(this.ControllerContext.HttpContext.Request.QueryString,
this.ViewData, CmsContext);
string modeData = this.Request.QueryString[CmsGlobal.VisualDesignModeKey];
if (!StringExtensions.IsNullOrEmptyTrim(modeData))
{
CmsContext.IsDesignMode = true;
}
CmsContext.UrlHelper = Url;
}
/// <summary>
/// Gets the page.
/// </summary>
protected virtual void InitPage()
{
string pageUrl;
var routeValues = this.RouteData.Values;
if (routeValues["pageUrl"] == null)
{
pageUrl = "";
}
else
pageUrl = routeValues["pageUrl"].ToString().ToLower();
var parameterUrl = pageUrl;
if (string.IsNullOrEmpty(pageUrl))
{
foreach (var defaultPageName in CmsGlobal.DefaultPageNames)
{
Cms_Page = CachedData.GetPage(Application.ApplicationName, defaultPageName);
if (Cms_Page != null)
{
break;
}
}
}
else
{
string outPageVirtualPath;
Cms_Page = CachedData.GetPageByUrl(pageUrl, Application.ApplicationName, out outPageVirtualPath);
if (!string.IsNullOrEmpty(outPageVirtualPath))
parameterUrl = pageUrl.Substring(outPageVirtualPath.Length);
if (parameterUrl.StartsWith("/"))
{
parameterUrl = parameterUrl.Substring(1);
}
}
if (Cms_Page == null)
{
throw new Everest.CmsServices.Exceptions.PageNotFoundException(pageUrl);
}
CmsContext.PageRouteData = RouteData.ParseCmsPageRouteValues(System.Web.HttpContext.Current, this.RouteData.Values, Cms_Page, parameterUrl);
}
protected virtual ActionResult ExecutePluginPostAction(IEnumerable<IControllerPlugin> controllerModules, ActionResult actionResult)
{
//execute controller modules
if (Request.HttpMethod == "GET")
{
foreach (var item in controllerModules)
{
actionResult = item.AfterGetExecute(actionResult);
}
}
else
{
foreach (var item in controllerModules)
{
actionResult = item.AfterPostExecute(actionResult);
}
}
return actionResult;
}
protected virtual ActionResult ExecutePluginsPreAction(IEnumerable<IControllerPlugin> controllerModules)
{
//execute controller modules
ActionResult actionResult = null;
if (Request.HttpMethod == "GET")
{
foreach (var plugin in controllerModules)
{
plugin.Initialize(this);
actionResult = plugin.PreGetExecute();
if (actionResult != null)
{
break;
}
}
}
else
{
foreach (var plugin in controllerModules)
{
plugin.Initialize(this);
actionResult = plugin.PrePostExecute();
if (actionResult != null)
{
break;
}
}
}
return actionResult;
}
/// <summary>
/// Gets or sets the action result helper.
/// </summary>
/// <value>The action result helper.</value>
public CmsActionResultHelper ActionResultHelper { get; private set; }
#endregion
#region override View Method
/// <summary>
/// Views the path.
/// </summary>
/// <param name="viewVirtualPath">The view virtual path.</param>
/// <param name="masterVirtualPath">The master virtual path.</param>
/// <param name="model">The model.</param>
/// <returns></returns>
public ViewResult ViewPath(string viewVirtualPath, string masterVirtualPath, object model)
{
if (model != null)
{
base.ViewData.Model = model;
}
return new VirtualPathViewResult { ViewVirtualPath = viewVirtualPath, MasterVirtualPath = masterVirtualPath, ViewData = base.ViewData, TempData = base.TempData };
}
#endregion
#region RedirectToContentPage
/// <summary>
/// Redirects to content page.
/// </summary>
/// <param name="pageName">Name of the page.</param>
/// <returns></returns>
public ActionResult RedirectToContentPage(string pageName)
{
return RedirectToContentPage(pageName, new RouteValueDictionary());
}
/// <summary>
/// Redirects to content page.
/// </summary>
/// <param name="pageName">Name of the page.</param>
/// <param name="values">The values.</param>
/// <returns></returns>
public ActionResult RedirectToContentPage(string pageName, object values)
{
RouteValueDictionary routeValues = new RouteValueDictionary(values);
return RedirectToContentPage(pageName, routeValues);
}
/// <summary>
/// Redirects to content page.
/// </summary>
/// <param name="pageName">Name of the page.</param>
/// <param name="dictionary">The dictionary.</param>
/// <returns></returns>
public ActionResult RedirectToContentPage(string pageName, IDictionary<string, object> dictionary)
{
RouteValueDictionary routeValues = new RouteValueDictionary(dictionary);
return RedirectToContentPage(pageName, routeValues);
}
/// <summary>
/// Redirects to content page.
/// </summary>
/// <param name="pageName">Name of the page.</param>
/// <param name="routeValues">The route values.</param>
/// <returns></returns>
private ActionResult RedirectToContentPage(string pageName, RouteValueDictionary routeValues)
{
routeValues["pageName"] = pageName;
return RedirectToAction("Execute", routeValues);
}
#endregion
#region RenderContentTemplate
/// <summary>
/// Renders the content template.
/// </summary>
/// <param name="contentTemplateName">Name of the content template.</param>
/// <returns></returns>
public string RenderContentTemplate(string contentTemplateName)
{
return RenderContentTemplate(contentTemplateName, null);
}
/// <summary>
/// Renders the content template.
/// </summary>
/// <param name="contentTemplateName">Name of the content template.</param>
/// <param name="propertySettings">The property settings.</param>
/// <returns></returns>
public string RenderContentTemplate(string contentTemplateName, object propertySettings)
{
var contentTemplate = CachedData.GetContentTemplate(Application.ApplicationName, contentTemplateName);
return RenderContentTemplate(contentTemplate, propertySettings);
}
/// <summary>
/// Renders the content template.
/// </summary>
/// <param name="contentTemplateUUID">The content template UUID.</param>
/// <returns></returns>
public string RenderContentTemplate(Guid contentTemplateUUID)
{
return RenderContentTemplate(contentTemplateUUID, null);
}
/// <summary>
/// Renders the content template.
/// </summary>
/// <param name="contentTemplateUUID">The content template UUID.</param>
/// <param name="propertySettings">The property settings.</param>
/// <returns></returns>
public string RenderContentTemplate(Guid contentTemplateUUID, object propertySettings)
{
var contentTemplate = CachedData.GetContentTemplate(Application.ApplicationName, contentTemplateUUID);
return RenderContentTemplate(contentTemplate, propertySettings);
}
/// <summary>
/// Renders the content template.
/// </summary>
/// <param name="contentTemplate">The content template.</param>
/// <param name="propertySettings">The property settings.</param>
/// <returns></returns>
public string RenderContentTemplate(Cms_ContentTemplate contentTemplate, object propertySettings)
{
Hashtable props = new Hashtable();
if (propertySettings != null)
{
props = HtmlExtensionUtility.GetPropertyHash(propertySettings);
}
props.Add("ContentTemplate", contentTemplate);
var virtualPath = contentTemplate.GetVirtualPath();
return GetHtmlHelper().RenderUserControl(virtualPath, props);
}
private HtmlHelper GetHtmlHelper()
{
return new HtmlHelper(new ViewContext(this.ControllerContext, new ViewMock(), ViewData, TempData, Response.Output), new ViewContainer(ViewData));
}
internal class ViewContainer : IViewDataContainer
{
public ViewContainer(ViewDataDictionary viewData)
{
ViewData = viewData;
}
#region IViewDataContainer Members
public ViewDataDictionary ViewData
{
get;
set;
}
#endregion
}
/// <summary>
///
/// </summary>
internal class ViewMock : IView
{
#region IView Members
public void Render(ViewContext viewContext, System.IO.TextWriter writer)
{
}
#endregion
}
#endregion
protected override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
if (filterContext.Exception is ResourceNotFoundException)
{
return;
}
if (Application == null)
{
return;
}
//if (Application.Release.HasValue && Application.Release.Value)
//{
IEnumerable<CustomError> customErrors = CachedData.GetCustomErrors(Application.ApplicationName);
HttpStatusCode statusCode = HttpStatusCode.Generic;
HttpException httpException = filterContext.Exception as HttpException;
if (httpException != null)
{
statusCode = (HttpStatusCode)httpException.GetHttpCode();
}
var customError = customErrors.Where(c => c.HttpStatusCode == statusCode).FirstOrDefault();
if (customError == null)
{
customError = customErrors.Where(c => c.HttpStatusCode == HttpStatusCode.Generic).FirstOrDefault();
}
if (customError != null)
{
var errorPage = CachedData.GetPageByVirtualPath(Application.ApplicationName, customError.Redirect.ToLower());
if (errorPage != null)
{
//if the error pagename equal current requested page name,ignore the exception handler.
if (Cms_Page == null || errorPage.PageName != Cms_Page.PageName)
{
RouteValueDictionary valueDic = new RouteValueDictionary();
valueDic.Add("aspxerrorpath", HttpUtility.UrlPathEncode(this.Request.Path));
var pageUrl = Everest.CmsServices.MvcHelper.UrlHelperExtensions.GenerateContextPageUrl(this.Url, errorPage, valueDic);
if (!StringExtensions.IsNullOrEmptyTrim(pageUrl))
{
//filterContext.Result = new MVCTransferResult(pageUrl); Could not using MVCTransferResult, it will cause the Unauthorized status doest work.
filterContext.Result = new RedirectResult(pageUrl);
filterContext.ExceptionHandled = true;
}
}
}
// filterContext.ExceptionHandled = true;
}
//}
}
private ActionResult ApplicationNotFound()
{
if (Request.Url.AbsolutePath == Request.FilePath)
{
return new RedirectResult("~/account/login");
}
throw new ResourceNotFoundException();
}
}
}
|