--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-12-10 12:03:27 -08:00
56 changed files with 507 additions and 172 deletions

View File

@@ -0,0 +1,5 @@
SET CDIR = %CD%
call "%ProgramFiles%\Windows Azure SDK\v1.3\bin\setenv.cmd"
csrun /devstore
csrun /run:"%CDIR %\build\Compile\Orchard.Azure.CloudService.csx";"%CDIR %\src\Orchard.Azure\Orchard.Azure.CloudService\ServiceConfiguration.cscfg" /launchbrowser
pause

View File

@@ -83,32 +83,27 @@ namespace Orchard.Azure.Environment.Configuration {
} }
} }
class Content { static ShellSettings ParseSettings(string text)
public string Name { get; set; } {
public string DataProvider { get; set; }
public string DataConnectionString { get; set; }
public string DataPrefix { get; set; }
public string RequestUrlHost { get; set; }
public string RequestUrlPrefix { get; set; }
public string State { get; set; }
}
static ShellSettings ParseSettings(string text) {
var shellSettings = new ShellSettings(); var shellSettings = new ShellSettings();
if ( String.IsNullOrEmpty(text) ) if (String.IsNullOrEmpty(text))
return shellSettings; return shellSettings;
string[] settings = text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string[] settings = text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach ( var setting in settings ) { foreach (var setting in settings)
{
string[] settingFields = setting.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries); string[] settingFields = setting.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
int fieldsLength = settingFields.Length; int fieldsLength = settingFields.Length;
if ( fieldsLength != 2 ) if (fieldsLength != 2)
continue; continue;
for ( int i = 0; i < fieldsLength; i++ ) { for (int i = 0; i < fieldsLength; i++)
{
settingFields[i] = settingFields[i].Trim(); settingFields[i] = settingFields[i].Trim();
} }
if ( settingFields[1] != "null" ) { if (settingFields[1] != "null")
switch ( settingFields[0] ) { {
switch (settingFields[0])
{
case "Name": case "Name":
shellSettings.Name = settingFields[1]; shellSettings.Name = settingFields[1];
break; break;
@@ -130,24 +125,38 @@ namespace Orchard.Azure.Environment.Configuration {
case "RequestUrlPrefix": case "RequestUrlPrefix":
shellSettings.RequestUrlPrefix = settingFields[1]; shellSettings.RequestUrlPrefix = settingFields[1];
break; break;
case "EncryptionAlgorithm":
shellSettings.EncryptionAlgorithm = settingFields[1];
break;
case "EncryptionKey":
shellSettings.EncryptionKey = settingFields[1];
break;
case "EncryptionIV":
shellSettings.EncryptionIV = settingFields[1];
break;
} }
} }
} }
return shellSettings; return shellSettings;
} }
static string ComposeSettings(ShellSettings settings) { static string ComposeSettings(ShellSettings settings)
if ( settings == null ) {
if (settings == null)
return ""; return "";
return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\n", return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n",
settings.Name, settings.Name,
settings.DataProvider, settings.DataProvider,
settings.DataConnectionString ?? "null", settings.DataConnectionString ?? "null",
settings.DataTablePrefix ?? "null", settings.DataTablePrefix ?? "null",
settings.RequestUrlHost ?? "null", settings.RequestUrlHost ?? "null",
settings.RequestUrlPrefix ?? "null", settings.RequestUrlPrefix ?? "null",
settings.State != null ? settings.State.ToString() : String.Empty); settings.State != null ? settings.State.ToString() : String.Empty,
settings.EncryptionAlgorithm ?? "null",
settings.EncryptionKey ?? "null",
settings.EncryptionIV ?? "null"
);
} }
} }
} }

View File

@@ -1,13 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="OrchardCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"> <ServiceDefinition name="OrchardCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="Orchard.Azure.Web"> <WebRole name="Orchard.Azure.Web">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="HttpIn" endpointName="HttpIn" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings> <ConfigurationSettings>
<Setting name="DiagnosticsConnectionString" /> <Setting name="DiagnosticsConnectionString" />
<Setting name="DataConnectionString" /> <Setting name="DataConnectionString" />

View File

@@ -75,8 +75,9 @@
<Reference Include="System.Data.DataSetExtensions"> <Reference Include="System.Data.DataSetExtensions">
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="System.Data.SqlServerCe, Version=3.5.1.0, PublicKeyToken=89845dcd8080cc91"> <Reference Include="System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Web.ApplicationServices"> <Reference Include="System.Web.ApplicationServices">
<Private>False</Private> <Private>False</Private>

View File

@@ -60,6 +60,11 @@ namespace Orchard.Tests.Stubs {
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); } set { throw new NotImplementedException(); }
} }
public int PageSize {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
} }
public class StubUser : IUser { public class StubUser : IUser {

View File

@@ -11,20 +11,29 @@ using Orchard.Themes;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Core.Containers.Controllers { namespace Orchard.Core.Containers.Controllers {
using Orchard.Settings;
public class ItemController : Controller { public class ItemController : Controller {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IContainersPathConstraint _containersPathConstraint; private readonly IContainersPathConstraint _containersPathConstraint;
private readonly ISiteService _siteService;
public ItemController(
IContentManager contentManager,
IContainersPathConstraint containersPathConstraint,
IShapeFactory shapeFactory,
ISiteService siteService) {
public ItemController(IContentManager contentManager, IContainersPathConstraint containersPathConstraint, IShapeFactory shapeFactory) {
_contentManager = contentManager; _contentManager = contentManager;
_containersPathConstraint = containersPathConstraint; _containersPathConstraint = containersPathConstraint;
_siteService = siteService;
Shape = shapeFactory; Shape = shapeFactory;
} }
dynamic Shape { get; set; } dynamic Shape { get; set; }
[Themed] [Themed]
public ActionResult Display(string path, Pager pager) { public ActionResult Display(string path, PagerParameters pagerParameters) {
var matchedPath = _containersPathConstraint.FindPath(path); var matchedPath = _containersPathConstraint.FindPath(path);
if (string.IsNullOrEmpty(matchedPath)) { if (string.IsNullOrEmpty(matchedPath)) {
throw new ApplicationException("404 - should not have passed path constraint"); throw new ApplicationException("404 - should not have passed path constraint");
@@ -51,7 +60,8 @@ namespace Orchard.Core.Containers.Controllers {
var descendingOrder = container.As<ContainerPart>().Record.OrderByDirection == (int) OrderByDirection.Descending; var descendingOrder = container.As<ContainerPart>().Record.OrderByDirection == (int) OrderByDirection.Descending;
query = query.OrderBy(container.As<ContainerPart>().Record.OrderByProperty, descendingOrder); query = query.OrderBy(container.As<ContainerPart>().Record.OrderByProperty, descendingOrder);
pager.PageSize = pager.PageSize != Pager.PageSizeDefault && container.As<ContainerPart>().Record.Paginated Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
pager.PageSize = pagerParameters.PageSize != null && container.As<ContainerPart>().Record.Paginated
? pager.PageSize ? pager.PageSize
: container.As<ContainerPart>().Record.PageSize; : container.As<ContainerPart>().Record.PageSize;
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count()); var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());

View File

@@ -17,6 +17,7 @@ using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
using Orchard.UI.Notify; using Orchard.UI.Notify;
using Orchard.Settings;
namespace Orchard.Core.Contents.Controllers { namespace Orchard.Core.Contents.Controllers {
[ValidateInput(false)] [ValidateInput(false)]
@@ -24,17 +25,20 @@ namespace Orchard.Core.Contents.Controllers {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IContentDefinitionManager _contentDefinitionManager; private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ITransactionManager _transactionManager; private readonly ITransactionManager _transactionManager;
private readonly ISiteService _siteService;
public AdminController( public AdminController(
IOrchardServices orchardServices, IOrchardServices orchardServices,
IContentManager contentManager, IContentManager contentManager,
IContentDefinitionManager contentDefinitionManager, IContentDefinitionManager contentDefinitionManager,
ITransactionManager transactionManager, ITransactionManager transactionManager,
ISiteService siteService,
IShapeFactory shapeFactory) { IShapeFactory shapeFactory) {
Services = orchardServices; Services = orchardServices;
_contentManager = contentManager; _contentManager = contentManager;
_contentDefinitionManager = contentDefinitionManager; _contentDefinitionManager = contentDefinitionManager;
_transactionManager = transactionManager; _transactionManager = transactionManager;
_siteService = siteService;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
Shape = shapeFactory; Shape = shapeFactory;
@@ -45,7 +49,8 @@ namespace Orchard.Core.Contents.Controllers {
public Localizer T { get; set; } public Localizer T { get; set; }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public ActionResult List(ListContentsViewModel model, Pager pager) { public ActionResult List(ListContentsViewModel model, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
if (model.ContainerId != null && _contentManager.GetLatest((int)model.ContainerId) == null) if (model.ContainerId != null && _contentManager.GetLatest((int)model.ContainerId) == null)
return HttpNotFound(); return HttpNotFound();

View File

@@ -104,6 +104,7 @@
<Compile Include="Contents\Shapes.cs" /> <Compile Include="Contents\Shapes.cs" />
<Compile Include="Contents\ViewModels\PublishContentViewModel.cs" /> <Compile Include="Contents\ViewModels\PublishContentViewModel.cs" />
<Compile Include="Navigation\Services\MainMenuNavigationProvider.cs" /> <Compile Include="Navigation\Services\MainMenuNavigationProvider.cs" />
<Compile Include="Routable\Events\ISlugEventHandler.cs" />
<Compile Include="Routable\ResourceManifest.cs" /> <Compile Include="Routable\ResourceManifest.cs" />
<Compile Include="Routable\Services\RoutableHomePageProvider.cs" /> <Compile Include="Routable\Services\RoutableHomePageProvider.cs" />
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" /> <Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />

View File

@@ -0,0 +1,17 @@
using Orchard.Events;
namespace Orchard.Core.Routable.Events {
public interface ISlugEventHandler : IEventHandler {
void FillingSlugFromTitle(FillSlugContext context);
void FilledSlugFromTitle(FillSlugContext context);
}
public class FillSlugContext {
public FillSlugContext(string slug) {
Slug = slug;
}
public string Slug { get; set; }
public bool Adjusted { get; set; }
}
}

View File

@@ -1,18 +1,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects; using Orchard.ContentManagement.Aspects;
using Orchard.Core.Common.Models; using Orchard.Core.Common.Models;
using Orchard.Core.Routable.Events;
using Orchard.Core.Routable.Models; using Orchard.Core.Routable.Models;
namespace Orchard.Core.Routable.Services { namespace Orchard.Core.Routable.Services {
public class RoutableService : IRoutableService { public class RoutableService : IRoutableService {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IEnumerable<ISlugEventHandler> _slugEventHandlers;
public RoutableService(IContentManager contentManager) { public RoutableService(IContentManager contentManager, IEnumerable<ISlugEventHandler> slugEventHandlers) {
_contentManager = contentManager; _contentManager = contentManager;
_slugEventHandlers = slugEventHandlers;
} }
public void FixContainedPaths(IRoutableAspect part) { public void FixContainedPaths(IRoutableAspect part) {
@@ -27,23 +32,47 @@ namespace Orchard.Core.Routable.Services {
} }
} }
public static string RemoveDiacritics(string slug) {
string stFormD = slug.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for (int ich = 0; ich < stFormD.Length; ich++) {
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
if (uc != UnicodeCategory.NonSpacingMark) {
sb.Append(stFormD[ich]);
}
}
return (sb.ToString().Normalize(NormalizationForm.FormC));
}
public void FillSlugFromTitle<TModel>(TModel model) where TModel : IRoutableAspect { public void FillSlugFromTitle<TModel>(TModel model) where TModel : IRoutableAspect {
if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title)) if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title))
return; return;
var slug = model.Title; FillSlugContext slugContext = new FillSlugContext(model.Title);
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+");
slug = dissallowed.Replace(slug, "-"); foreach(ISlugEventHandler slugEventHandler in _slugEventHandlers) {
slug = slug.Trim('-'); slugEventHandler.FillingSlugFromTitle(slugContext);
}
if (slug.Length > 1000) if (!slugContext.Adjusted) {
slug = slug.Substring(0, 1000); var disallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+");
// dots are not allowed at the begin and the end of routes slugContext.Slug = disallowed.Replace(slugContext.Slug, "-").Trim('-');
slug = slug.Trim('.');
model.Slug = slug.ToLowerInvariant(); if (slugContext.Slug.Length > 1000)
slugContext.Slug = slugContext.Slug.Substring(0, 1000);
// dots are not allowed at the begin and the end of routes
slugContext.Slug = RemoveDiacritics(slugContext.Slug.Trim('.').ToLower());
}
foreach (ISlugEventHandler slugEventHandler in _slugEventHandlers) {
slugEventHandler.FilledSlugFromTitle(slugContext);
}
model.Slug = slugContext.Slug;
} }
public string GenerateUniqueSlug(IRoutableAspect part, IEnumerable<string> existingPaths) { public string GenerateUniqueSlug(IRoutableAspect part, IEnumerable<string> existingPaths) {

View File

@@ -90,6 +90,7 @@ namespace Orchard.Core.Settings {
.Column<string>("HomePage") .Column<string>("HomePage")
.Column<string>("SiteCulture") .Column<string>("SiteCulture")
.Column<string>("ResourceDebugMode", c => c.WithDefault("FromAppSetting")) .Column<string>("ResourceDebugMode", c => c.WithDefault("FromAppSetting"))
.Column<int>("PageSize")
); );
return 1; return 1;

View File

@@ -8,28 +8,39 @@ namespace Orchard.Core.Settings.Models {
get { return Record.PageTitleSeparator; } get { return Record.PageTitleSeparator; }
set { Record.PageTitleSeparator = value; } set { Record.PageTitleSeparator = value; }
} }
public string SiteName { public string SiteName {
get { return Record.SiteName; } get { return Record.SiteName; }
set { Record.SiteName = value; } set { Record.SiteName = value; }
} }
public string SiteSalt { public string SiteSalt {
get { return Record.SiteSalt; } get { return Record.SiteSalt; }
} }
public string SuperUser { public string SuperUser {
get { return Record.SuperUser; } get { return Record.SuperUser; }
set { Record.SuperUser = value; } set { Record.SuperUser = value; }
} }
public string HomePage { public string HomePage {
get { return Record.HomePage; } get { return Record.HomePage; }
set { Record.HomePage = value; } set { Record.HomePage = value; }
} }
public string SiteCulture { public string SiteCulture {
get { return Record.SiteCulture; } get { return Record.SiteCulture; }
set { Record.SiteCulture = value; } set { Record.SiteCulture = value; }
} }
public ResourceDebugMode ResourceDebugMode { public ResourceDebugMode ResourceDebugMode {
get { return Record.ResourceDebugMode; } get { return Record.ResourceDebugMode; }
set { Record.ResourceDebugMode = value; } set { Record.ResourceDebugMode = value; }
} }
public int PageSize {
get { return Record.PageSize; }
set { Record.PageSize = value; }
}
} }
} }

View File

@@ -3,12 +3,26 @@ using Orchard.Settings;
namespace Orchard.Core.Settings.Models { namespace Orchard.Core.Settings.Models {
public class SiteSettingsPartRecord : ContentPartRecord { public class SiteSettingsPartRecord : ContentPartRecord {
public const int DefaultPageSize = 10;
public SiteSettingsPartRecord() {
PageSize = DefaultPageSize;
}
public virtual string SiteSalt { get; set; } public virtual string SiteSalt { get; set; }
public virtual string SiteName { get; set; } public virtual string SiteName { get; set; }
public virtual string SuperUser { get; set; } public virtual string SuperUser { get; set; }
public virtual string PageTitleSeparator { get; set; } public virtual string PageTitleSeparator { get; set; }
public virtual string HomePage { get; set; } public virtual string HomePage { get; set; }
public virtual string SiteCulture { get; set; } public virtual string SiteCulture { get; set; }
public virtual ResourceDebugMode ResourceDebugMode { get; set; } public virtual ResourceDebugMode ResourceDebugMode { get; set; }
public virtual int PageSize { get; set; }
} }
} }

View File

@@ -15,8 +15,7 @@ namespace Orchard.Core.Settings.ViewModels {
get { return Site.ContentItem.Id; } get { return Site.ContentItem.Id; }
} }
public string PageTitleSeparator public string PageTitleSeparator {
{
get { return Site.Record.PageTitleSeparator; } get { return Site.Record.PageTitleSeparator; }
set { Site.Record.PageTitleSeparator = value; } set { Site.Record.PageTitleSeparator = value; }
} }
@@ -40,5 +39,10 @@ namespace Orchard.Core.Settings.ViewModels {
get { return Site.As<SiteSettingsPart>().ResourceDebugMode; } get { return Site.As<SiteSettingsPart>().ResourceDebugMode; }
set { Site.As<SiteSettingsPart>().ResourceDebugMode = value; } set { Site.As<SiteSettingsPart>().ResourceDebugMode = value; }
} }
public int PageSize {
get { return Site.As<SiteSettingsPart>().PageSize; }
set { Site.As<SiteSettingsPart>().PageSize = value; }
}
} }
} }

View File

@@ -36,4 +36,9 @@
@Html.DropDownList("ResourceDebugMode", resourceDebugMode) @Html.DropDownList("ResourceDebugMode", resourceDebugMode)
<span class="hint">@T("Determines whether scripts and stylesheets load in their debuggable or minified form.")</span> <span class="hint">@T("Determines whether scripts and stylesheets load in their debuggable or minified form.")</span>
</div> </div>
<div>
<label for="DefaultPageSize">@T("Default number of items per page")</label>
@Html.TextBoxFor(m => m.PageSize, new { @class = "textMedium" })
<span class="hint">@T("Determines the default number of items that are shown per page.")</span>
</div>
</fieldset> </fieldset>

View File

@@ -25,7 +25,7 @@ namespace Orchard.Blogs {
var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null; var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : null;
if (blogCount > 0 && singleBlog == null) { if (blogCount > 0 && singleBlog == null) {
menu.Add(T("List"), "3", menu.Add(T("Manage Blogs"), "3",
item => item.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.MetaListOwnBlogs)); item => item.Action("List", "BlogAdmin", new {area = "Orchard.Blogs"}).Permission(Permissions.MetaListOwnBlogs));
} }
else if (singleBlog != null) else if (singleBlog != null)

View File

@@ -15,6 +15,8 @@ using Orchard.UI.Navigation;
using Orchard.UI.Notify; using Orchard.UI.Notify;
namespace Orchard.Blogs.Controllers { namespace Orchard.Blogs.Controllers {
using Orchard.Settings;
[ValidateInput(false), Admin] [ValidateInput(false), Admin]
public class BlogAdminController : Controller, IUpdateModel { public class BlogAdminController : Controller, IUpdateModel {
private readonly IBlogService _blogService; private readonly IBlogService _blogService;
@@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly ITransactionManager _transactionManager; private readonly ITransactionManager _transactionManager;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly ISiteService _siteService;
public BlogAdminController( public BlogAdminController(
IOrchardServices services, IOrchardServices services,
@@ -30,6 +33,7 @@ namespace Orchard.Blogs.Controllers {
IContentManager contentManager, IContentManager contentManager,
ITransactionManager transactionManager, ITransactionManager transactionManager,
IBlogSlugConstraint blogSlugConstraint, IBlogSlugConstraint blogSlugConstraint,
ISiteService siteService,
IShapeFactory shapeFactory) { IShapeFactory shapeFactory) {
Services = services; Services = services;
_blogService = blogService; _blogService = blogService;
@@ -37,6 +41,7 @@ namespace Orchard.Blogs.Controllers {
_contentManager = contentManager; _contentManager = contentManager;
_transactionManager = transactionManager; _transactionManager = transactionManager;
_blogSlugConstraint = blogSlugConstraint; _blogSlugConstraint = blogSlugConstraint;
_siteService = siteService;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Shape = shapeFactory; Shape = shapeFactory;
} }
@@ -147,7 +152,8 @@ namespace Orchard.Blogs.Controllers {
return View((object)viewModel); return View((object)viewModel);
} }
public ActionResult Item(int blogId, Pager pager) { public ActionResult Item(int blogId, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
BlogPart blogPart = _blogService.Get(blogId, VersionOptions.Latest).As<BlogPart>(); BlogPart blogPart = _blogService.Get(blogId, VersionOptions.Latest).As<BlogPart>();
if (blogPart == null) if (blogPart == null)

View File

@@ -13,6 +13,8 @@ using Orchard.Themes;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
namespace Orchard.Blogs.Controllers { namespace Orchard.Blogs.Controllers {
using Orchard.Settings;
[Themed] [Themed]
public class BlogController : Controller { public class BlogController : Controller {
private readonly IOrchardServices _services; private readonly IOrchardServices _services;
@@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers {
private readonly IFeedManager _feedManager; private readonly IFeedManager _feedManager;
private readonly IWorkContextAccessor _workContextAccessor; private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider; private readonly IHomePageProvider _routableHomePageProvider;
private readonly ISiteService _siteService;
public BlogController( public BlogController(
IOrchardServices services, IOrchardServices services,
@@ -31,13 +34,15 @@ namespace Orchard.Blogs.Controllers {
IFeedManager feedManager, IFeedManager feedManager,
IShapeFactory shapeFactory, IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor, IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) { IEnumerable<IHomePageProvider> homePageProviders,
ISiteService siteService) {
_services = services; _services = services;
_blogService = blogService; _blogService = blogService;
_blogPostService = blogPostService; _blogPostService = blogPostService;
_blogSlugConstraint = blogSlugConstraint; _blogSlugConstraint = blogSlugConstraint;
_feedManager = feedManager; _feedManager = feedManager;
_workContextAccessor = workContextAccessor; _workContextAccessor = workContextAccessor;
_siteService = siteService;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name); _routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
Shape = shapeFactory; Shape = shapeFactory;
@@ -59,7 +64,8 @@ namespace Orchard.Blogs.Controllers {
return View((object)viewModel); return View((object)viewModel);
} }
public ActionResult Item(string blogSlug, Pager pager) { public ActionResult Item(string blogSlug, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug); var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug);
if (correctedSlug == null) if (correctedSlug == null)
return HttpNotFound(); return HttpNotFound();

View File

@@ -9,6 +9,8 @@ using Orchard.ContentManagement.Aspects;
using Orchard.Core.Contents.Settings; using Orchard.Core.Contents.Settings;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.AntiForgery; using Orchard.Mvc.AntiForgery;
using Orchard.Security;
using Orchard.Security.Permissions;
using Orchard.UI.Admin; using Orchard.UI.Admin;
using Orchard.UI.Notify; using Orchard.UI.Notify;
@@ -84,9 +86,6 @@ namespace Orchard.Blogs.Controllers {
//todo: the content shape template has extra bits that the core contents module does not (remove draft functionality) //todo: the content shape template has extra bits that the core contents module does not (remove draft functionality)
//todo: - move this extra functionality there or somewhere else that's appropriate? //todo: - move this extra functionality there or somewhere else that's appropriate?
public ActionResult Edit(int blogId, int postId) { public ActionResult Edit(int blogId, int postId) {
if (!Services.Authorizer.Authorize(Permissions.EditOwnBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
var blog = _blogService.Get(blogId, VersionOptions.Latest); var blog = _blogService.Get(blogId, VersionOptions.Latest);
if (blog == null) if (blog == null)
return HttpNotFound(); return HttpNotFound();
@@ -95,6 +94,9 @@ namespace Orchard.Blogs.Controllers {
if (post == null) if (post == null)
return HttpNotFound(); return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.EditOthersBlogPost, post.ContentItem, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
dynamic model = Services.ContentManager.BuildEditor(post); dynamic model = Services.ContentManager.BuildEditor(post);
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation. // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
return View((object)model); return View((object)model);

View File

@@ -5,7 +5,7 @@ namespace Orchard.Blogs {
public class Migrations : DataMigrationImpl { public class Migrations : DataMigrationImpl {
public int Create() { public int Create() {
SchemaBuilder.CreateTable("BlogPartArchiveRecord", SchemaBuilder.CreateTable("BlogPartArchiveRecord",
table => table table => table
.Column<int>("Id", column => column.PrimaryKey().Identity()) .Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<int>("Year") .Column<int>("Year")
@@ -14,21 +14,21 @@ namespace Orchard.Blogs {
.Column<int>("BlogPart_id") .Column<int>("BlogPart_id")
); );
SchemaBuilder.CreateTable("BlogPartRecord", SchemaBuilder.CreateTable("BlogPartRecord",
table => table table => table
.ContentPartRecord() .ContentPartRecord()
.Column<string>("Description", c => c.Unlimited()) .Column<string>("Description", c => c.Unlimited())
.Column<int>("PostCount") .Column<int>("PostCount")
); );
SchemaBuilder.CreateTable("RecentBlogPostsPartRecord", SchemaBuilder.CreateTable("RecentBlogPostsPartRecord",
table => table table => table
.ContentPartRecord() .ContentPartRecord()
.Column<string>("BlogSlug") .Column<string>("BlogSlug")
.Column<int>("Count") .Column<int>("Count")
); );
SchemaBuilder.CreateTable("BlogArchivesPartRecord", SchemaBuilder.CreateTable("BlogArchivesPartRecord",
table => table table => table
.ContentPartRecord() .ContentPartRecord()
.Column<string>("BlogSlug", c => c.WithLength(255)) .Column<string>("BlogSlug", c => c.WithLength(255))

View File

@@ -82,6 +82,7 @@
<Compile Include="Routing\IsArchiveConstraint.cs" /> <Compile Include="Routing\IsArchiveConstraint.cs" />
<Compile Include="Routing\BlogSlugConstraint.cs" /> <Compile Include="Routing\BlogSlugConstraint.cs" />
<Compile Include="Routing\BlogSlugConstraintUpdator.cs" /> <Compile Include="Routing\BlogSlugConstraintUpdator.cs" />
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
<Compile Include="Services\BlogService.cs" /> <Compile Include="Services\BlogService.cs" />
<Compile Include="Controllers\BlogController.cs" /> <Compile Include="Controllers\BlogController.cs" />
<Compile Include="Models\BlogPart.cs" /> <Compile Include="Models\BlogPart.cs" />

View File

@@ -0,0 +1,49 @@
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Blogs.Security {
[UsedImplicitly]
public class BlogAuthorizationEventHandler : IAuthorizationServiceEventHandler {
public void Checking(CheckAccessContext context) { }
public void Complete(CheckAccessContext context) { }
public void Adjust(CheckAccessContext context) {
if (!context.Granted &&
context.Content.Is<ICommonPart>()) {
if (OwnerVariationExists(context.Permission) &&
HasOwnership(context.User, context.Content)) {
context.Adjusted = true;
context.Permission = GetOwnerVariation(context.Permission);
}
}
}
private static bool HasOwnership(IUser user, IContent content) {
if (user == null || content == null)
return false;
var common = content.As<ICommonPart>();
if (common == null || common.Owner == null)
return false;
return user.Id == common.Owner.Id;
}
private static bool OwnerVariationExists(Permission permission) {
return GetOwnerVariation(permission) != null;
}
private static Permission GetOwnerVariation(Permission permission) {
if (permission.Name == Permissions.PublishOthersBlogPost.Name)
return Permissions.PublishOwnBlogPost;
if (permission.Name == Permissions.EditOthersBlogPost.Name)
return Permissions.EditOwnBlogPost;
if (permission.Name == Permissions.DeleteOthersBlogPost.Name)
return Permissions.DeleteOwnBlogPost;
return null;
}
}
}

View File

@@ -123,7 +123,7 @@ namespace Orchard.Blogs.Services {
string password) { string password) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null);
var array = new XRpcArray(); var array = new XRpcArray();
foreach (var blog in _blogService.Get()) { foreach (var blog in _blogService.Get()) {
@@ -144,7 +144,7 @@ namespace Orchard.Blogs.Services {
int numberOfPosts) { int numberOfPosts) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null);
var blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId)); var blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId));
if (blog == null) if (blog == null)
@@ -166,7 +166,7 @@ namespace Orchard.Blogs.Services {
IEnumerable<IXmlRpcDriver> drivers) { IEnumerable<IXmlRpcDriver> drivers) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(Permissions.EditOwnBlogPost, user, null); _authorizationService.CheckAccess(publish ? Permissions.PublishOthersBlogPost : Permissions.EditOthersBlogPost, user, null);
var blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId)); var blog = _contentManager.Get<BlogPart>(Convert.ToInt32(blogId));
if (blog == null) if (blog == null)
@@ -216,7 +216,7 @@ namespace Orchard.Blogs.Services {
IEnumerable<IXmlRpcDriver> drivers) { IEnumerable<IXmlRpcDriver> drivers) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); _authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null);
var blogPost = _blogPostService.Get(postId, VersionOptions.Latest); var blogPost = _blogPostService.Get(postId, VersionOptions.Latest);
if (blogPost == null) if (blogPost == null)
@@ -231,15 +231,13 @@ namespace Orchard.Blogs.Services {
} }
private bool MetaWeblogEditPost(int postId, string userName, string password, XRpcStruct content, bool publish, IEnumerable<IXmlRpcDriver> drivers) { private bool MetaWeblogEditPost(int postId, string userName, string password, XRpcStruct content, bool publish, IEnumerable<IXmlRpcDriver> drivers) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); _authorizationService.CheckAccess(publish ? Permissions.PublishOthersBlogPost : Permissions.EditOthersBlogPost, user, null);
var blogPost = _blogPostService.Get(postId, VersionOptions.DraftRequired); var blogPost = _blogPostService.Get(postId, VersionOptions.DraftRequired);
if (blogPost == null) if (blogPost == null)
throw new ArgumentException(); throw new ArgumentException();
var title = content.Optional<string>("title"); var title = content.Optional<string>("title");
var description = content.Optional<string>("description"); var description = content.Optional<string>("description");
var slug = content.Optional<string>("wp_slug"); var slug = content.Optional<string>("wp_slug");
@@ -259,7 +257,7 @@ namespace Orchard.Blogs.Services {
private bool MetaWeblogDeletePost(string appkey, string postId, string userName, string password, bool publish, IEnumerable<IXmlRpcDriver> drivers) { private bool MetaWeblogDeletePost(string appkey, string postId, string userName, string password, bool publish, IEnumerable<IXmlRpcDriver> drivers) {
var user = _membershipService.ValidateUser(userName, password); var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null); _authorizationService.CheckAccess(Permissions.DeleteOthersBlogPost, user, null);
var blogPost = _blogPostService.Get(Convert.ToInt32(postId), VersionOptions.Latest); var blogPost = _blogPostService.Get(Convert.ToInt32(postId), VersionOptions.Latest);
if (blogPost == null) if (blogPost == null)

View File

@@ -14,12 +14,20 @@ using Orchard.Comments.ViewModels;
using Orchard.Comments.Services; using Orchard.Comments.Services;
namespace Orchard.Comments.Controllers { namespace Orchard.Comments.Controllers {
using Orchard.Settings;
[ValidateInput(false)] [ValidateInput(false)]
public class AdminController : Controller { public class AdminController : Controller {
private readonly ICommentService _commentService; private readonly ICommentService _commentService;
private readonly ISiteService _siteService;
public AdminController(IOrchardServices services, ICommentService commentService, IShapeFactory shapeFactory) { public AdminController(
IOrchardServices services,
ICommentService commentService,
ISiteService siteService,
IShapeFactory shapeFactory) {
_commentService = commentService; _commentService = commentService;
_siteService = siteService;
Services = services; Services = services;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
@@ -31,7 +39,9 @@ namespace Orchard.Comments.Controllers {
public Localizer T { get; set; } public Localizer T { get; set; }
dynamic Shape { get; set; } dynamic Shape { get; set; }
public ActionResult Index(CommentIndexOptions options, Pager pager) { public ActionResult Index(CommentIndexOptions options, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
// Default options // Default options
if (options == null) if (options == null)
options = new CommentIndexOptions(); options = new CommentIndexOptions();

View File

@@ -2,7 +2,7 @@
white-space:nowrap; white-space:nowrap;
} }
table.items tr { table.items tr {
background:#f7f7f7; background:#fff;
} }
table.items tr.anonymous { table.items tr.anonymous {
background:#fff; background:#fff;

View File

@@ -36,7 +36,7 @@ namespace Orchard.ContentTypes.Services {
public Localizer T { get; set; } public Localizer T { get; set; }
public IEnumerable<EditTypeViewModel> GetTypes() { public IEnumerable<EditTypeViewModel> GetTypes() {
return _contentDefinitionManager.ListTypeDefinitions().Select(ctd => new EditTypeViewModel(ctd)); return _contentDefinitionManager.ListTypeDefinitions().Select(ctd => new EditTypeViewModel(ctd)).OrderBy(m => m.DisplayName);
} }
public EditTypeViewModel GetType(string name) { public EditTypeViewModel GetType(string name) {

View File

@@ -1,5 +1,6 @@
.orchard-contenttypes #main h2 { .orchard-contenttypes #main h2 {
margin:1.5em 0 0; margin:1.5em 0 0;
border-bottom:1px solid #ccc;
} }
#main .properties p { #main .properties p {

View File

@@ -1,6 +1,7 @@
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Localization; using Orchard.Localization;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
using Orchard.Security;
namespace Orchard.Packaging { namespace Orchard.Packaging {
[OrchardFeature("Gallery")] [OrchardFeature("Gallery")]
@@ -12,11 +13,14 @@ namespace Orchard.Packaging {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Gallery"), "30", menu => menu builder.Add(T("Gallery"), "30", menu => menu
.Add(T("Modules"), "1.0", item => item .Add(T("Modules"), "1.0", item => item
.Action("Modules", "Gallery", new { area = "Orchard.Packaging" })) .Action("Modules", "Gallery", new { area = "Orchard.Packaging" })
.Permission(StandardPermissions.SiteOwner))
.Add(T("Themes"), "2.0", item => item .Add(T("Themes"), "2.0", item => item
.Action("Themes", "Gallery", new { area = "Orchard.Packaging" })) .Action("Themes", "Gallery", new { area = "Orchard.Packaging" })
.Permission(StandardPermissions.SiteOwner))
.Add(T("Feeds"), "3.0", item => item .Add(T("Feeds"), "3.0", item => item
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" }))); .Action("Sources", "Gallery", new { area = "Orchard.Packaging" })
.Permission(StandardPermissions.SiteOwner)));
} }
} }
} }

View File

@@ -9,6 +9,7 @@ using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Packaging.Services; using Orchard.Packaging.Services;
using Orchard.Packaging.ViewModels; using Orchard.Packaging.ViewModels;
using Orchard.Security;
using Orchard.Themes; using Orchard.Themes;
using Orchard.UI.Admin; using Orchard.UI.Admin;
using Orchard.UI.Notify; using Orchard.UI.Notify;
@@ -26,36 +27,51 @@ namespace Orchard.Packaging.Controllers {
public GalleryController( public GalleryController(
IPackageManager packageManager, IPackageManager packageManager,
IPackagingSourceManager packagingSourceManager, IPackagingSourceManager packagingSourceManager,
INotifier notifier) { INotifier notifier,
IOrchardServices services) {
_packageManager = packageManager; _packageManager = packageManager;
_packagingSourceManager = packagingSourceManager; _packagingSourceManager = packagingSourceManager;
_notifier = notifier; _notifier = notifier;
Services = services;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
public IOrchardServices Services { get; set; }
public Localizer T { get; set; } public Localizer T { get; set; }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public ActionResult Sources() { public ActionResult Sources() {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list sources")))
return new HttpUnauthorizedResult();
return View(new PackagingSourcesViewModel { return View(new PackagingSourcesViewModel {
Sources = _packagingSourceManager.GetSources(), Sources = _packagingSourceManager.GetSources(),
}); });
} }
public ActionResult Remove(int id) { public ActionResult Remove(int id) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove sources")))
return new HttpUnauthorizedResult();
_packagingSourceManager.RemoveSource(id); _packagingSourceManager.RemoveSource(id);
_notifier.Information(T("The feed has been removed successfully.")); _notifier.Information(T("The feed has been removed successfully."));
return RedirectToAction("Sources"); return RedirectToAction("Sources");
} }
public ActionResult AddSource() { public ActionResult AddSource() {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources")))
return new HttpUnauthorizedResult();
return View(new PackagingAddSourceViewModel()); return View(new PackagingAddSourceViewModel());
} }
[HttpPost] [HttpPost]
public ActionResult AddSource(string url) { public ActionResult AddSource(string url) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources")))
return new HttpUnauthorizedResult();
try { try {
if (!String.IsNullOrEmpty(url)) { if (!String.IsNullOrEmpty(url)) {
if (!url.StartsWith("http")) { if (!url.StartsWith("http")) {
@@ -96,6 +112,9 @@ namespace Orchard.Packaging.Controllers {
} }
public ActionResult Modules(int? sourceId) { public ActionResult Modules(int? sourceId) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list modules")))
return new HttpUnauthorizedResult();
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
var sources = selectedSource != null var sources = selectedSource != null
@@ -123,6 +142,9 @@ namespace Orchard.Packaging.Controllers {
} }
public ActionResult Themes(int? sourceId) { public ActionResult Themes(int? sourceId) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list themes")))
return new HttpUnauthorizedResult();
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
var sources = selectedSource != null var sources = selectedSource != null
@@ -138,6 +160,9 @@ namespace Orchard.Packaging.Controllers {
} }
public ActionResult Install(string packageId, string version, int sourceId, string redirectTo) { public ActionResult Install(string packageId, string version, int sourceId, string redirectTo) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to install packages")))
return new HttpUnauthorizedResult();
var source = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault(); var source = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
if (source == null) { if (source == null) {

View File

@@ -8,6 +8,7 @@ using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData; using Orchard.FileSystems.AppData;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Packaging.Services; using Orchard.Packaging.Services;
using Orchard.Security;
using Orchard.Themes; using Orchard.Themes;
using Orchard.UI.Admin; using Orchard.UI.Admin;
using Orchard.UI.Notify; using Orchard.UI.Notify;
@@ -25,40 +26,61 @@ namespace Orchard.Packaging.Controllers {
public PackagingServicesController( public PackagingServicesController(
IPackageManager packageManager, IPackageManager packageManager,
INotifier notifier, INotifier notifier,
IAppDataFolderRoot appDataFolderRoot) { IAppDataFolderRoot appDataFolderRoot,
IOrchardServices services) {
_packageManager = packageManager; _packageManager = packageManager;
_notifier = notifier; _notifier = notifier;
_appDataFolderRoot = appDataFolderRoot; _appDataFolderRoot = appDataFolderRoot;
Services = services;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
public Localizer T { get; set; } public Localizer T { get; set; }
public IOrchardServices Services { get; set; }
public ActionResult AddTheme(string returnUrl) { public ActionResult AddTheme(string returnUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add themes")))
return new HttpUnauthorizedResult();
return View(); return View();
} }
[HttpPost, ActionName("AddTheme")] [HttpPost, ActionName("AddTheme")]
public ActionResult AddThemePOST(string returnUrl) { public ActionResult AddThemePOST(string returnUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add themes")))
return new HttpUnauthorizedResult();
return InstallPackage(returnUrl, Request.RawUrl); return InstallPackage(returnUrl, Request.RawUrl);
} }
[HttpPost, ActionName("RemoveTheme")] [HttpPost, ActionName("RemoveTheme")]
public ActionResult RemoveThemePOST(string themeId, string returnUrl, string retryUrl) { public ActionResult RemoveThemePOST(string themeId, string returnUrl, string retryUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove themes")))
return new HttpUnauthorizedResult();
return UninstallPackage(PackagingSourceManager.ThemesPrefix + themeId, returnUrl, retryUrl); return UninstallPackage(PackagingSourceManager.ThemesPrefix + themeId, returnUrl, retryUrl);
} }
public ActionResult AddModule(string returnUrl) { public ActionResult AddModule(string returnUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules")))
return new HttpUnauthorizedResult();
return View(); return View();
} }
[HttpPost, ActionName("AddModule")] [HttpPost, ActionName("AddModule")]
public ActionResult AddModulePOST(string returnUrl) { public ActionResult AddModulePOST(string returnUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules")))
return new HttpUnauthorizedResult();
return InstallPackage(returnUrl, Request.RawUrl); return InstallPackage(returnUrl, Request.RawUrl);
} }
public ActionResult InstallPackage(string returnUrl, string retryUrl) { public ActionResult InstallPackage(string returnUrl, string retryUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to install packages")))
return new HttpUnauthorizedResult();
try { try {
if (Request.Files != null && if (Request.Files != null &&
Request.Files.Count > 0 && Request.Files.Count > 0 &&
@@ -90,6 +112,9 @@ namespace Orchard.Packaging.Controllers {
} }
public ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) { public ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) {
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to uninstall packages")))
return new HttpUnauthorizedResult();
try { try {
_packageManager.Uninstall(id, HostingEnvironment.MapPath("~/")); _packageManager.Uninstall(id, HostingEnvironment.MapPath("~/"));

View File

@@ -2,6 +2,7 @@
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Drivers;
using Orchard.Core.Common.Services; using Orchard.Core.Common.Services;
using Orchard.Mvc;
using Orchard.PublishLater.Models; using Orchard.PublishLater.Models;
using Orchard.PublishLater.Services; using Orchard.PublishLater.Services;
using Orchard.PublishLater.ViewModels; using Orchard.PublishLater.ViewModels;
@@ -58,22 +59,24 @@ namespace Orchard.PublishLater.Drivers {
updater.TryUpdateModel(model, Prefix, null, null); updater.TryUpdateModel(model, Prefix, null, null);
if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) && !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) { if (Services.WorkContext.Resolve<IHttpContextAccessor>().Current().Request.Form["submit.Save"] == "submit.PublishLater") {
DateTime scheduled; if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) && !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) {
string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime); DateTime scheduled;
string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime);
// use an english culture as it is the one used by jQuery.datepicker by default // use an english culture as it is the one used by jQuery.datepicker by default
if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) { if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) {
model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime(); model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime();
_publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value); _publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value);
}
else {
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
}
} }
else { else if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) || !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) {
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime)); updater.AddModelError(Prefix, T("Both the date and time need to be specified for when this is to be published. If you don't want to schedule publishing then click Save or Publish Now."));
} }
} }
else if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) || !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) {
updater.AddModelError(Prefix, T("Both the date and time need to be specified for when this is to be published. If you don't want to schedule publishing then clear both the date and time fields."));
}
return ContentShape("Parts_PublishLater_Edit", return ContentShape("Parts_PublishLater_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));

View File

@@ -7,7 +7,7 @@
--> -->
<!-- edit shape just get default placement --> <!-- edit shape just get default placement -->
<!-- edit "shape" --> <!-- edit "shape" -->
<Place Parts_PublishLater_Edit="Sidebar:22"/><!-- immediately following the contents module's save button --> <Place Parts_PublishLater_Edit="Sidebar:25"/><!-- immediately following the contents module's Publish Now button -->
<!-- default positioning --> <!-- default positioning -->
<Match DisplayType="SummaryAdmin"> <Match DisplayType="SummaryAdmin">
<Place Parts_PublishLater_Metadata_SummaryAdmin="Meta:1"/> <Place Parts_PublishLater_Metadata_SummaryAdmin="Meta:1"/>

View File

@@ -6,9 +6,25 @@ html.dyn input.hinted {
color:#ccc; color:#ccc;
font-style:italic; font-style:italic;
} }
fieldset.publish-later-datetime {
float:left;
clear:none;
white-space: nowrap;
vertical-align: middle;
}
fieldset.publish-later-datetime legend {
display:none;
}
fieldset.publish-later-datetime input {
padding:1px;
text-align:center;
color:#666;
}
input#PublishLater_ScheduledPublishDate { input#PublishLater_ScheduledPublishDate {
width:49%; width:39%;
} }
input#PublishLater_ScheduledPublishTime { input#PublishLater_ScheduledPublishTime {
width:43%; width:33%;
} }

View File

@@ -12,6 +12,7 @@
@Html.EditorFor(m => m.ScheduledPublishDate) @Html.EditorFor(m => m.ScheduledPublishDate)
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishTime")">@T("Time")</label> <label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishTime")">@T("Time")</label>
@Html.EditorFor(m => m.ScheduledPublishTime) @Html.EditorFor(m => m.ScheduledPublishTime)
<button type="submit" name="submit.Save" value="submit.PublishLater">@T("Publish Later")</button>
</fieldset> </fieldset>
@using(Script.Foot()) { @using(Script.Foot()) {
<script type="text/javascript"> <script type="text/javascript">

View File

@@ -15,19 +15,24 @@ using Orchard.Collections;
using Orchard.Themes; using Orchard.Themes;
namespace Orchard.Search.Controllers { namespace Orchard.Search.Controllers {
using Orchard.Settings;
[ValidateInput(false), Themed] [ValidateInput(false), Themed]
public class SearchController : Controller { public class SearchController : Controller {
private readonly ISearchService _searchService; private readonly ISearchService _searchService;
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly ISiteService _siteService;
public SearchController( public SearchController(
IOrchardServices services, IOrchardServices services,
ISearchService searchService, ISearchService searchService,
IContentManager contentManager, IContentManager contentManager,
ISiteService siteService,
IShapeFactory shapeFactory) { IShapeFactory shapeFactory) {
Services = services; Services = services;
_searchService = searchService; _searchService = searchService;
_contentManager = contentManager; _contentManager = contentManager;
_siteService = siteService;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
@@ -39,7 +44,8 @@ namespace Orchard.Search.Controllers {
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
dynamic Shape { get; set; } dynamic Shape { get; set; }
public ActionResult Index(Pager pager, string q = "") { public ActionResult Index(PagerParameters pagerParameters, string q = "") {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var searchFields = Services.WorkContext.CurrentSite.As<SearchSettingsPart>().SearchedFields; var searchFields = Services.WorkContext.CurrentSite.As<SearchSettingsPart>().SearchedFields;
IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { }); IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { });

View File

@@ -7,17 +7,12 @@
Model.ContentItems.Classes.Add("search-results"); Model.ContentItems.Classes.Add("search-results");
} }
<h1>@Html.TitleForPage(T("Search").Text)</h1> <h1>@Html.TitleForPage(T("Search").Text)</h1>
@using(Html.BeginForm("index", "search", new { area = "Orchard.Search" }, FormMethod.Get, new { @class = "search group" })) {
<fieldset>
@Html.TextBox("q", Model.Query)
<button type="submit">@T("Search")</button>
</fieldset>
}
@if (HasText(Model.Query)) { @if (HasText(Model.Query)) {
if (searchResults.Count() == 0) { if (searchResults.Count() == 0) {
<p class="search-summary">@T.Plural("the <em>one</em> result", "<em>zero</em> results", searchResults.Count())</p> <p class="search-summary">@T.Plural("There is <em>one</em> result", "<em>zero</em> results", searchResults.Count())</p>
} else { } else {
<p class="search-summary">@T.Plural("the <em>one</em> result", "<em>{1} - {2}</em> of <em>{0}</em> results", Model.TotalItemCount, Model.StartPosition, Model.EndPosition)</p> <p class="search-summary">@T.Plural("There is <em>one</em> result", "<em>{1} - {2}</em> of <em>{0}</em> results", Model.TotalItemCount, Model.StartPosition, Model.EndPosition)</p>
} }
} }
@if (searchResults != null && searchResults.Count() > 0) { @if (searchResults != null && searchResults.Count() > 0) {

View File

@@ -8,6 +8,7 @@ using Orchard.Commands.Builtin;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Handlers;
using Orchard.ContentManagement.MetaData.Builders; using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Core.Settings.Models;
using Orchard.Data.Migration.Interpreters; using Orchard.Data.Migration.Interpreters;
using Orchard.Data.Providers; using Orchard.Data.Providers;
using Orchard.Data.Migration; using Orchard.Data.Migration;
@@ -172,6 +173,11 @@ namespace Orchard.Setup {
get { return ResourceDebugMode.FromAppSetting; } get { return ResourceDebugMode.FromAppSetting; }
set { throw new NotImplementedException(); } set { throw new NotImplementedException(); }
} }
public int PageSize {
get { return SiteSettingsPartRecord.DefaultPageSize; }
set { throw new NotImplementedException(); }
}
} }
} }
} }

View File

@@ -4,23 +4,28 @@ using Orchard.ContentManagement;
using Orchard.DisplayManagement; using Orchard.DisplayManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Settings;
using Orchard.Tags.Services; using Orchard.Tags.Services;
using Orchard.Tags.ViewModels; using Orchard.Tags.ViewModels;
using Orchard.Themes; using Orchard.Themes;
using Orchard.UI.Navigation;
namespace Orchard.Tags.Controllers { namespace Orchard.Tags.Controllers {
[ValidateInput(false), Themed] [ValidateInput(false), Themed]
public class HomeController : Controller { public class HomeController : Controller {
private readonly ITagService _tagService; private readonly ITagService _tagService;
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly ISiteService _siteService;
private readonly dynamic _shapeFactory; private readonly dynamic _shapeFactory;
public HomeController( public HomeController(
ITagService tagService, ITagService tagService,
IContentManager contentManager, IContentManager contentManager,
ISiteService siteService,
IShapeFactory shapeFactory) { IShapeFactory shapeFactory) {
_tagService = tagService; _tagService = tagService;
_contentManager = contentManager; _contentManager = contentManager;
_siteService = siteService;
_shapeFactory = shapeFactory; _shapeFactory = shapeFactory;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -34,21 +39,26 @@ namespace Orchard.Tags.Controllers {
return View(model); return View(model);
} }
public ActionResult Search(string tagName) { public ActionResult Search(string tagName, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var tag = _tagService.GetTagByName(tagName); var tag = _tagService.GetTagByName(tagName);
if (tag == null) { if (tag == null) {
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
var list = _shapeFactory.List(); var taggedItems = _tagService.GetTaggedContentItems(tag.Id, pager.GetStartIndex(), pager.PageSize)
foreach (var taggedContentItem in _tagService.GetTaggedContentItems(tag.Id)) { .Select(item => _contentManager.BuildDisplay(item, "Summary"));
list.Add(_contentManager.BuildDisplay(taggedContentItem, "Summary"));
}
var list = _shapeFactory.List();
list.AddRange(taggedItems);
var totalItemCount = _tagService.GetTaggedContentItemCount(tag.Id);
var viewModel = new TagsSearchViewModel { var viewModel = new TagsSearchViewModel {
TagName = tag.TagName, TagName = tag.TagName,
List = list List = list,
Pager = _shapeFactory.Pager(pager).TotalItemCount(totalItemCount)
}; };
return View(viewModel); return View(viewModel);

View File

@@ -9,6 +9,10 @@ namespace Orchard.Tags.Services {
TagRecord GetTagByName(string tagName); TagRecord GetTagByName(string tagName);
IEnumerable<IContent> GetTaggedContentItems(int tagId); IEnumerable<IContent> GetTaggedContentItems(int tagId);
IEnumerable<IContent> GetTaggedContentItems(int tagId, VersionOptions options); IEnumerable<IContent> GetTaggedContentItems(int tagId, VersionOptions options);
IEnumerable<IContent> GetTaggedContentItems(int tagId, int skip, int count);
IEnumerable<IContent> GetTaggedContentItems(int tagId, int skip, int count, VersionOptions versionOptions);
int GetTaggedContentItemCount(int tagId);
int GetTaggedContentItemCount(int tagId, VersionOptions versionOptions);
TagRecord CreateTag(string tagName); TagRecord CreateTag(string tagName);

View File

@@ -119,6 +119,27 @@ namespace Orchard.Tags.Services {
.Where(c => c != null); .Where(c => c != null);
} }
public IEnumerable<IContent> GetTaggedContentItems(int tagId, int skip, int take) {
return GetTaggedContentItems(tagId, skip, take, VersionOptions.Published);
}
public IEnumerable<IContent> GetTaggedContentItems(int tagId, int skip, int take, VersionOptions options) {
return _contentTagRepository
.Fetch(x => x.TagRecord.Id == tagId)
.Skip(skip)
.Take(take)
.Select(t => _orchardServices.ContentManager.Get(t.TagsPartRecord.Id, options))
.Where(c => c != null);
}
public int GetTaggedContentItemCount(int tagId) {
return GetTaggedContentItemCount(tagId, VersionOptions.Published);
}
public int GetTaggedContentItemCount(int tagId, VersionOptions options) {
return GetTaggedContentItems(tagId, options).Count();
}
private void TagContentItem(TagsPartRecord tagsPartRecord, string tagName) { private void TagContentItem(TagsPartRecord tagsPartRecord, string tagName) {
var tagRecord = GetTagByName(tagName); var tagRecord = GetTagByName(tagName);
var tagsContentItems = new ContentTagRecord { TagsPartRecord = tagsPartRecord, TagRecord = tagRecord }; var tagsContentItems = new ContentTagRecord { TagsPartRecord = tagsPartRecord, TagRecord = tagRecord };

View File

@@ -2,5 +2,6 @@
public class TagsSearchViewModel { public class TagsSearchViewModel {
public string TagName { get; set; } public string TagName { get; set; }
public dynamic List { get; set; } public dynamic List { get; set; }
public dynamic Pager { get; set; }
} }
} }

View File

@@ -1,11 +1,10 @@
@model Orchard.Tags.ViewModels.TagsSearchViewModel @model Orchard.Tags.ViewModels.TagsSearchViewModel
@{ @{
Html.AddTitleParts(T("Tags").ToString()); Html.AddTitleParts(T("Tags").ToString());
Html.AddTitleParts(T("Contents tagged with {0}", Model.TagName).ToString()); Html.AddTitleParts(T("Contents tagged with {0}", Model.TagName).ToString());
Model.List.Classes.Add("tagged-posts"); Model.List.Classes.Add("tagged-posts");
Model.List.Classes.Add("content-items"); Model.List.Classes.Add("content-items");
} }
<h1 class="page-title">@T("Contents tagged with <span>{0}</span>", Model.TagName)</h1> <h1 class="page-title">@T("Contents tagged with <span>{0}</span>", Model.TagName)</h1>
@Display(Model.List) @Display(Model.List)
@Display(Model.Pager)

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.ContentManagement; using Orchard.ContentManagement;
@@ -27,8 +28,16 @@ namespace Orchard.Widgets.Drivers {
public Localizer T { get; set; } public Localizer T { get; set; }
protected override DriverResult Editor(LayerPart layerPart, dynamic shapeHelper) { protected override DriverResult Editor(LayerPart layerPart, dynamic shapeHelper) {
return ContentShape("Parts_Widgets_LayerPart", var results = new List<DriverResult> {
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix)); ContentShape("Parts_Widgets_LayerPart",
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix))
};
if (layerPart.Id > 0)
results.Add(ContentShape("Widget_DeleteButton",
deleteButton => deleteButton));
return Combined(results.ToArray());
} }
protected override DriverResult Editor(LayerPart layerPart, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(LayerPart layerPart, IUpdateModel updater, dynamic shapeHelper) {

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations; using System.Collections.Generic;
using JetBrains.Annotations;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers; using Orchard.ContentManagement.Drivers;
using Orchard.Widgets.Models; using Orchard.Widgets.Models;
@@ -18,8 +19,16 @@ namespace Orchard.Widgets.Drivers {
widgetPart.AvailableZones = _widgetsService.GetZones(); widgetPart.AvailableZones = _widgetsService.GetZones();
widgetPart.AvailableLayers = _widgetsService.GetLayers(); widgetPart.AvailableLayers = _widgetsService.GetLayers();
return ContentShape("Parts_Widgets_WidgetPart", var results = new List<DriverResult> {
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix)); ContentShape("Parts_Widgets_WidgetPart",
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix))
};
if (widgetPart.Id > 0)
results.Add(ContentShape("Widget_DeleteButton",
deleteButton => deleteButton));
return Combined(results.ToArray());
} }
protected override DriverResult Editor(WidgetPart widgetPart, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(WidgetPart widgetPart, IUpdateModel updater, dynamic shapeHelper) {

View File

@@ -130,6 +130,9 @@
<Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" /> <Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" />
<Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" /> <Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Views\Widget.DeleteButton.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -1,4 +1,5 @@
<Placement> <Placement>
<Place Widget_DeleteButton="Sidebar:25"/>
<Place Parts_Widgets_LayerPart="Content:1"/> <Place Parts_Widgets_LayerPart="Content:1"/>
<Place Parts_Widgets_WidgetPart="Content:1"/> <Place Parts_Widgets_WidgetPart="Content:1"/>
<Place Parts_Widgets_WidegetBagPart="Content:5"/> <Place Parts_Widgets_WidegetBagPart="Content:5"/>

View File

@@ -2,8 +2,4 @@
@using (Html.BeginFormAntiForgeryPost()) { @using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary() @Html.ValidationSummary()
@Display(Model) @Display(Model)
<fieldset>
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
</fieldset>
} }

View File

@@ -2,8 +2,4 @@
@using (Html.BeginFormAntiForgeryPost()) { @using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary() @Html.ValidationSummary()
@Display(Model) @Display(Model)
<fieldset>
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
</fieldset>
} }

View File

@@ -0,0 +1,3 @@
<fieldset class="delete-button">
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
</fieldset>

View File

@@ -732,7 +732,6 @@ table.items th, table.items td {
border-spacing:0px; border-spacing:0px;
display:table-cell; display:table-cell;
padding:8px 12px; padding:8px 12px;
vertical-align:middle;
} }
/* Content item lists /* Content item lists
@@ -748,6 +747,7 @@ table.items th, table.items td {
margin:0; margin:0;
overflow:hidden; overflow:hidden;
padding:0 1.4em .8em; padding:0 1.4em .8em;
border-bottom:1px solid #eaeaea;
} }
.contentItems li.last { .contentItems li.last {
border-bottom:none; border-bottom:none;
@@ -859,51 +859,28 @@ table.items th, table.items td {
} }
/* Core Contents and Orchard.PublishLater */ /* Core Contents and Orchard.PublishLater */
.edit-item-sidebar
{
border:1px solid #d3d3d3;
padding:8px;
/*CSS3 properties*/
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f7f7f7', endColorstr='#f5f5f5');
background: -webkit-gradient(linear, 0 0, 0 100%, from(#f7f7f7), to(#f5f5f5));
background: -moz-linear-gradient(top, #f7f7f7, #f5f5f5);
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
.edit-item-sidebar fieldset { .edit-item-sidebar fieldset {
margin:0; margin:0;
padding:0; padding:0;
} }
fieldset.publish-button { fieldset.publish-button, fieldset.delete-button, fieldset.save-button {
clear:none; clear:none;
float:left; float:left;
}
fieldset.save-button {
clear:left;
}
fieldset.publish-button {
margin: 0 12px; margin: 0 12px;
padding: 0 12px; padding: 0 12px;
border-left:1px solid #ccc; border-left:1px solid #ccc;
} }
fieldset.save-button { fieldset.delete-button {
clear:none; margin: 0 0 0 12px;
float:left;
padding-right:0;
width:auto;
}
fieldset.publish-later-datetime {
float:left;
}
fieldset.publish-later-datetime legend {
display:none;
}
fieldset.publish-later-datetime input {
padding:1px;
text-align:center;
color:#666;
} }
/* Fields /* Fields
***************************************************************/ ***************************************************************/
/* TextField */ /* TextField */

View File

@@ -18,7 +18,7 @@ namespace Orchard.Data.Providers {
public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) { public override IPersistenceConfigurer GetPersistenceConfigurer(bool createDatabase) {
var persistence = MsSqlConfiguration.MsSql2008; var persistence = MsSqlConfiguration.MsSql2008;
if (string.IsNullOrEmpty(_connectionString)) { if (string.IsNullOrEmpty(_connectionString)) {
throw new NotImplementedException(); throw new ArgumentException("The connection string is empty");
} }
persistence = persistence.ConnectionString(_connectionString); persistence = persistence.ConnectionString(_connectionString);
return persistence; return persistence;

View File

@@ -165,7 +165,7 @@ namespace Orchard.Environment.Extensions {
foreach(var dup in duplicates) { foreach(var dup in duplicates) {
sb.Append(T("Extension '{0}' has been found from the following locations: {1}.\r\n", dup.Key, string.Join(", ", dup.Select(e => e.Location + "/" + e.Id)))); sb.Append(T("Extension '{0}' has been found from the following locations: {1}.\r\n", dup.Key, string.Join(", ", dup.Select(e => e.Location + "/" + e.Id))));
} }
sb.Append(T("This issue can be usually by solved by removing or renamig the conflicting extension.")); sb.Append(T("This issue can be usually by solved by removing or renaming the conflicting extension."));
Logger.Error(sb.ToString()); Logger.Error(sb.ToString());
throw new OrchardException(new LocalizedString(sb.ToString())); throw new OrchardException(new LocalizedString(sb.ToString()));
} }

View File

@@ -188,6 +188,7 @@
<Compile Include="Themes\ThemeManager.cs" /> <Compile Include="Themes\ThemeManager.cs" />
<Compile Include="UI\FlatPositionComparer.cs" /> <Compile Include="UI\FlatPositionComparer.cs" />
<Compile Include="UI\Navigation\Pager.cs" /> <Compile Include="UI\Navigation\Pager.cs" />
<Compile Include="UI\Navigation\PagerParameters.cs" />
<Compile Include="UI\Resources\IResourceManifestProvider.cs" /> <Compile Include="UI\Resources\IResourceManifestProvider.cs" />
<Compile Include="UI\Resources\ResourceManifestBuilder.cs" /> <Compile Include="UI\Resources\ResourceManifestBuilder.cs" />
<Compile Include="UI\Zones\LayoutWorkContext.cs" /> <Compile Include="UI\Zones\LayoutWorkContext.cs" />

View File

@@ -2,7 +2,7 @@
namespace Orchard.Settings { namespace Orchard.Settings {
/// <summary> /// <summary>
/// Interface provided by the "settings" model. /// Interface provided by the "settings" model.
/// </summary> /// </summary>
public interface ISite : IContent { public interface ISite : IContent {
string PageTitleSeparator { get; } string PageTitleSeparator { get; }
@@ -12,5 +12,6 @@ namespace Orchard.Settings {
string HomePage { get; set; } string HomePage { get; set; }
string SiteCulture { get; set; } string SiteCulture { get; set; }
ResourceDebugMode ResourceDebugMode { get; set; } ResourceDebugMode ResourceDebugMode { get; set; }
int PageSize { get; set; }
} }
} }

View File

@@ -1,22 +1,49 @@
namespace Orchard.UI.Navigation { using Orchard.Settings;
namespace Orchard.UI.Navigation {
public class Pager { public class Pager {
private const int PageDefault = 1; /// <summary>
public const int PageSizeDefault = 10; /// The default page number.
private int _pageSize; /// </summary>
private int _size; public const int PageDefault = 1;
public int Page { /// <summary>
get { return _pageSize > 0 ? _pageSize : PageDefault; } /// Constructs a new pager.
set { _pageSize = value; } /// </summary>
/// <param name="site">The site settings.</param>
/// <param name="pagerParameters">The pager parameters.</param>
public Pager(ISite site, PagerParameters pagerParameters)
: this(site, pagerParameters.Page, pagerParameters.PageSize) {
} }
public int PageSize { /// <summary>
get { return _size > 0 ? _size : PageSizeDefault; } /// Constructs a new pager.
set { _size = value; } /// </summary>
/// <param name="site">The site settings.</param>
/// <param name="page">The page parameter.</param>
/// <param name="pageSize">The page size parameter.</param>
public Pager(ISite site, int? page, int? pageSize) {
Page = (int) (page != null ? (page > 0 ? page : PageDefault) : PageDefault);
PageSize = pageSize ?? site.PageSize;
} }
/// <summary>
/// Gets or sets the current page number or the default page number if none is specified.
/// </summary>
public int Page { get; set; }
/// <summary>
/// Gets or sets the current page size or the site default size if none is specified.
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// Gets the current page start index.
/// </summary>
/// <param name="page">The current page number.</param>
/// <returns>The index in which the page starts.</returns>
public int GetStartIndex(int? page = null) { public int GetStartIndex(int? page = null) {
return ((page ?? Page) - 1)*PageSize; return ((page ?? Page) - PageDefault) * PageSize;
} }
} }
} }

View File

@@ -0,0 +1,13 @@
namespace Orchard.UI.Navigation {
public class PagerParameters {
/// <summary>
/// Gets or sets the current page number or null if none specified.
/// </summary>
public int? Page { get; set; }
/// <summary>
/// Gets or sets the current page size or null if none specified.
/// </summary>
public int? PageSize { get; set; }
}
}