mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -11,20 +11,29 @@ using Orchard.Themes;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Core.Containers.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
public class ItemController : Controller {
|
||||
private readonly IContentManager _contentManager;
|
||||
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;
|
||||
_containersPathConstraint = containersPathConstraint;
|
||||
_siteService = siteService;
|
||||
Shape = shapeFactory;
|
||||
}
|
||||
|
||||
dynamic Shape { get; set; }
|
||||
|
||||
[Themed]
|
||||
public ActionResult Display(string path, Pager pager) {
|
||||
public ActionResult Display(string path, PagerParameters pagerParameters) {
|
||||
var matchedPath = _containersPathConstraint.FindPath(path);
|
||||
if (string.IsNullOrEmpty(matchedPath)) {
|
||||
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;
|
||||
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
|
||||
: container.As<ContainerPart>().Record.PageSize;
|
||||
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());
|
||||
|
@@ -17,6 +17,7 @@ using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.Settings;
|
||||
|
||||
namespace Orchard.Core.Contents.Controllers {
|
||||
[ValidateInput(false)]
|
||||
@@ -24,17 +25,20 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly ISiteService _siteService;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices orchardServices,
|
||||
IContentManager contentManager,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
ITransactionManager transactionManager,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
Services = orchardServices;
|
||||
_contentManager = contentManager;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_transactionManager = transactionManager;
|
||||
_siteService = siteService;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
Shape = shapeFactory;
|
||||
@@ -45,7 +49,8 @@ namespace Orchard.Core.Contents.Controllers {
|
||||
public Localizer T { 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)
|
||||
return HttpNotFound();
|
||||
|
||||
|
@@ -104,6 +104,7 @@
|
||||
<Compile Include="Contents\Shapes.cs" />
|
||||
<Compile Include="Contents\ViewModels\PublishContentViewModel.cs" />
|
||||
<Compile Include="Navigation\Services\MainMenuNavigationProvider.cs" />
|
||||
<Compile Include="Routable\Events\ISlugEventHandler.cs" />
|
||||
<Compile Include="Routable\ResourceManifest.cs" />
|
||||
<Compile Include="Routable\Services\RoutableHomePageProvider.cs" />
|
||||
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />
|
||||
|
17
src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs
Normal file
17
src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs
Normal 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; }
|
||||
}
|
||||
}
|
@@ -1,18 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Routable.Events;
|
||||
using Orchard.Core.Routable.Models;
|
||||
|
||||
namespace Orchard.Core.Routable.Services {
|
||||
public class RoutableService : IRoutableService {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IEnumerable<ISlugEventHandler> _slugEventHandlers;
|
||||
|
||||
public RoutableService(IContentManager contentManager) {
|
||||
public RoutableService(IContentManager contentManager, IEnumerable<ISlugEventHandler> slugEventHandlers) {
|
||||
_contentManager = contentManager;
|
||||
_slugEventHandlers = slugEventHandlers;
|
||||
}
|
||||
|
||||
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 {
|
||||
if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title))
|
||||
return;
|
||||
|
||||
var slug = model.Title;
|
||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+");
|
||||
FillSlugContext slugContext = new FillSlugContext(model.Title);
|
||||
|
||||
slug = dissallowed.Replace(slug, "-");
|
||||
slug = slug.Trim('-');
|
||||
foreach(ISlugEventHandler slugEventHandler in _slugEventHandlers) {
|
||||
slugEventHandler.FillingSlugFromTitle(slugContext);
|
||||
}
|
||||
|
||||
if (slug.Length > 1000)
|
||||
slug = slug.Substring(0, 1000);
|
||||
if (!slugContext.Adjusted) {
|
||||
var disallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+");
|
||||
|
||||
// dots are not allowed at the begin and the end of routes
|
||||
slug = slug.Trim('.');
|
||||
slugContext.Slug = disallowed.Replace(slugContext.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) {
|
||||
|
@@ -90,6 +90,7 @@ namespace Orchard.Core.Settings {
|
||||
.Column<string>("HomePage")
|
||||
.Column<string>("SiteCulture")
|
||||
.Column<string>("ResourceDebugMode", c => c.WithDefault("FromAppSetting"))
|
||||
.Column<int>("PageSize")
|
||||
);
|
||||
|
||||
return 1;
|
||||
|
@@ -8,28 +8,39 @@ namespace Orchard.Core.Settings.Models {
|
||||
get { return Record.PageTitleSeparator; }
|
||||
set { Record.PageTitleSeparator = value; }
|
||||
}
|
||||
|
||||
public string SiteName {
|
||||
get { return Record.SiteName; }
|
||||
set { Record.SiteName = value; }
|
||||
}
|
||||
|
||||
public string SiteSalt {
|
||||
get { return Record.SiteSalt; }
|
||||
}
|
||||
|
||||
public string SuperUser {
|
||||
get { return Record.SuperUser; }
|
||||
set { Record.SuperUser = value; }
|
||||
}
|
||||
|
||||
public string HomePage {
|
||||
get { return Record.HomePage; }
|
||||
set { Record.HomePage = value; }
|
||||
}
|
||||
|
||||
public string SiteCulture {
|
||||
get { return Record.SiteCulture; }
|
||||
set { Record.SiteCulture = value; }
|
||||
}
|
||||
|
||||
public ResourceDebugMode ResourceDebugMode {
|
||||
get { return Record.ResourceDebugMode; }
|
||||
set { Record.ResourceDebugMode = value; }
|
||||
}
|
||||
|
||||
public int PageSize {
|
||||
get { return Record.PageSize; }
|
||||
set { Record.PageSize = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,12 +3,26 @@ using Orchard.Settings;
|
||||
|
||||
namespace Orchard.Core.Settings.Models {
|
||||
public class SiteSettingsPartRecord : ContentPartRecord {
|
||||
public const int DefaultPageSize = 10;
|
||||
|
||||
public SiteSettingsPartRecord() {
|
||||
PageSize = DefaultPageSize;
|
||||
}
|
||||
|
||||
public virtual string SiteSalt { get; set; }
|
||||
|
||||
public virtual string SiteName { get; set; }
|
||||
|
||||
public virtual string SuperUser { get; set; }
|
||||
|
||||
public virtual string PageTitleSeparator { get; set; }
|
||||
|
||||
public virtual string HomePage { get; set; }
|
||||
|
||||
public virtual string SiteCulture { get; set; }
|
||||
|
||||
public virtual ResourceDebugMode ResourceDebugMode { get; set; }
|
||||
|
||||
public virtual int PageSize { get; set; }
|
||||
}
|
||||
}
|
@@ -15,8 +15,7 @@ namespace Orchard.Core.Settings.ViewModels {
|
||||
get { return Site.ContentItem.Id; }
|
||||
}
|
||||
|
||||
public string PageTitleSeparator
|
||||
{
|
||||
public string PageTitleSeparator {
|
||||
get { return Site.Record.PageTitleSeparator; }
|
||||
set { Site.Record.PageTitleSeparator = value; }
|
||||
}
|
||||
@@ -40,5 +39,10 @@ namespace Orchard.Core.Settings.ViewModels {
|
||||
get { return Site.As<SiteSettingsPart>().ResourceDebugMode; }
|
||||
set { Site.As<SiteSettingsPart>().ResourceDebugMode = value; }
|
||||
}
|
||||
|
||||
public int PageSize {
|
||||
get { return Site.As<SiteSettingsPart>().PageSize; }
|
||||
set { Site.As<SiteSettingsPart>().PageSize = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,4 +36,9 @@
|
||||
@Html.DropDownList("ResourceDebugMode", resourceDebugMode)
|
||||
<span class="hint">@T("Determines whether scripts and stylesheets load in their debuggable or minified form.")</span>
|
||||
</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>
|
@@ -25,7 +25,7 @@ namespace Orchard.Blogs {
|
||||
var singleBlog = blogCount == 1 ? blogs.ElementAt(0) : 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));
|
||||
}
|
||||
else if (singleBlog != null)
|
||||
|
@@ -15,6 +15,8 @@ using Orchard.UI.Navigation;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Blogs.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
[ValidateInput(false), Admin]
|
||||
public class BlogAdminController : Controller, IUpdateModel {
|
||||
private readonly IBlogService _blogService;
|
||||
@@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
||||
private readonly ISiteService _siteService;
|
||||
|
||||
public BlogAdminController(
|
||||
IOrchardServices services,
|
||||
@@ -30,6 +33,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
IContentManager contentManager,
|
||||
ITransactionManager transactionManager,
|
||||
IBlogSlugConstraint blogSlugConstraint,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
Services = services;
|
||||
_blogService = blogService;
|
||||
@@ -37,6 +41,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
_contentManager = contentManager;
|
||||
_transactionManager = transactionManager;
|
||||
_blogSlugConstraint = blogSlugConstraint;
|
||||
_siteService = siteService;
|
||||
T = NullLocalizer.Instance;
|
||||
Shape = shapeFactory;
|
||||
}
|
||||
@@ -147,7 +152,8 @@ namespace Orchard.Blogs.Controllers {
|
||||
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>();
|
||||
|
||||
if (blogPart == null)
|
||||
|
@@ -13,6 +13,8 @@ using Orchard.Themes;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Blogs.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
[Themed]
|
||||
public class BlogController : Controller {
|
||||
private readonly IOrchardServices _services;
|
||||
@@ -22,6 +24,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
private readonly IFeedManager _feedManager;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IHomePageProvider _routableHomePageProvider;
|
||||
private readonly ISiteService _siteService;
|
||||
|
||||
public BlogController(
|
||||
IOrchardServices services,
|
||||
@@ -31,13 +34,15 @@ namespace Orchard.Blogs.Controllers {
|
||||
IFeedManager feedManager,
|
||||
IShapeFactory shapeFactory,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IEnumerable<IHomePageProvider> homePageProviders) {
|
||||
IEnumerable<IHomePageProvider> homePageProviders,
|
||||
ISiteService siteService) {
|
||||
_services = services;
|
||||
_blogService = blogService;
|
||||
_blogPostService = blogPostService;
|
||||
_blogSlugConstraint = blogSlugConstraint;
|
||||
_feedManager = feedManager;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_siteService = siteService;
|
||||
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
|
||||
Logger = NullLogger.Instance;
|
||||
Shape = shapeFactory;
|
||||
@@ -59,7 +64,8 @@ namespace Orchard.Blogs.Controllers {
|
||||
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);
|
||||
if (correctedSlug == null)
|
||||
return HttpNotFound();
|
||||
|
@@ -9,6 +9,8 @@ using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc.AntiForgery;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
using Orchard.UI.Admin;
|
||||
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: - move this extra functionality there or somewhere else that's appropriate?
|
||||
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);
|
||||
if (blog == null)
|
||||
return HttpNotFound();
|
||||
@@ -95,6 +94,9 @@ namespace Orchard.Blogs.Controllers {
|
||||
if (post == null)
|
||||
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);
|
||||
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
|
||||
return View((object)model);
|
||||
|
@@ -5,7 +5,7 @@ namespace Orchard.Blogs {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
|
||||
public int Create() {
|
||||
SchemaBuilder.CreateTable("BlogPartArchiveRecord",
|
||||
SchemaBuilder.CreateTable("BlogPartArchiveRecord",
|
||||
table => table
|
||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
||||
.Column<int>("Year")
|
||||
@@ -14,21 +14,21 @@ namespace Orchard.Blogs {
|
||||
.Column<int>("BlogPart_id")
|
||||
);
|
||||
|
||||
SchemaBuilder.CreateTable("BlogPartRecord",
|
||||
SchemaBuilder.CreateTable("BlogPartRecord",
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<string>("Description", c => c.Unlimited())
|
||||
.Column<int>("PostCount")
|
||||
);
|
||||
|
||||
SchemaBuilder.CreateTable("RecentBlogPostsPartRecord",
|
||||
SchemaBuilder.CreateTable("RecentBlogPostsPartRecord",
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<string>("BlogSlug")
|
||||
.Column<int>("Count")
|
||||
);
|
||||
|
||||
SchemaBuilder.CreateTable("BlogArchivesPartRecord",
|
||||
SchemaBuilder.CreateTable("BlogArchivesPartRecord",
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<string>("BlogSlug", c => c.WithLength(255))
|
||||
|
@@ -82,6 +82,7 @@
|
||||
<Compile Include="Routing\IsArchiveConstraint.cs" />
|
||||
<Compile Include="Routing\BlogSlugConstraint.cs" />
|
||||
<Compile Include="Routing\BlogSlugConstraintUpdator.cs" />
|
||||
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
|
||||
<Compile Include="Services\BlogService.cs" />
|
||||
<Compile Include="Controllers\BlogController.cs" />
|
||||
<Compile Include="Models\BlogPart.cs" />
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -123,7 +123,7 @@ namespace Orchard.Blogs.Services {
|
||||
string password) {
|
||||
|
||||
var user = _membershipService.ValidateUser(userName, password);
|
||||
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null);
|
||||
_authorizationService.CheckAccess(Permissions.EditOthersBlogPost, user, null);
|
||||
|
||||
var array = new XRpcArray();
|
||||
foreach (var blog in _blogService.Get()) {
|
||||
@@ -144,7 +144,7 @@ namespace Orchard.Blogs.Services {
|
||||
int numberOfPosts) {
|
||||
|
||||
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));
|
||||
if (blog == null)
|
||||
@@ -166,7 +166,7 @@ namespace Orchard.Blogs.Services {
|
||||
IEnumerable<IXmlRpcDriver> drivers) {
|
||||
|
||||
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));
|
||||
if (blog == null)
|
||||
@@ -216,7 +216,7 @@ namespace Orchard.Blogs.Services {
|
||||
IEnumerable<IXmlRpcDriver> drivers) {
|
||||
|
||||
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);
|
||||
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) {
|
||||
|
||||
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);
|
||||
if (blogPost == null)
|
||||
throw new ArgumentException();
|
||||
|
||||
|
||||
var title = content.Optional<string>("title");
|
||||
var description = content.Optional<string>("description");
|
||||
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) {
|
||||
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);
|
||||
if (blogPost == null)
|
||||
|
@@ -14,12 +14,20 @@ using Orchard.Comments.ViewModels;
|
||||
using Orchard.Comments.Services;
|
||||
|
||||
namespace Orchard.Comments.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller {
|
||||
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;
|
||||
_siteService = siteService;
|
||||
Services = services;
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
@@ -31,7 +39,9 @@ namespace Orchard.Comments.Controllers {
|
||||
public Localizer T { 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
|
||||
if (options == null)
|
||||
options = new CommentIndexOptions();
|
||||
|
@@ -2,7 +2,7 @@
|
||||
white-space:nowrap;
|
||||
}
|
||||
table.items tr {
|
||||
background:#f7f7f7;
|
||||
background:#fff;
|
||||
}
|
||||
table.items tr.anonymous {
|
||||
background:#fff;
|
||||
|
@@ -36,7 +36,7 @@ namespace Orchard.ContentTypes.Services {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
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) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
.orchard-contenttypes #main h2 {
|
||||
margin:1.5em 0 0;
|
||||
border-bottom:1px solid #ccc;
|
||||
}
|
||||
|
||||
#main .properties p {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.Security;
|
||||
|
||||
namespace Orchard.Packaging {
|
||||
[OrchardFeature("Gallery")]
|
||||
@@ -12,11 +13,14 @@ namespace Orchard.Packaging {
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder.Add(T("Gallery"), "30", menu => menu
|
||||
.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
|
||||
.Action("Themes", "Gallery", new { area = "Orchard.Packaging" }))
|
||||
.Action("Themes", "Gallery", new { area = "Orchard.Packaging" })
|
||||
.Permission(StandardPermissions.SiteOwner))
|
||||
.Add(T("Feeds"), "3.0", item => item
|
||||
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" })));
|
||||
.Action("Sources", "Gallery", new { area = "Orchard.Packaging" })
|
||||
.Permission(StandardPermissions.SiteOwner)));
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,6 +9,7 @@ using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Packaging.Services;
|
||||
using Orchard.Packaging.ViewModels;
|
||||
using Orchard.Security;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
@@ -26,36 +27,51 @@ namespace Orchard.Packaging.Controllers {
|
||||
public GalleryController(
|
||||
IPackageManager packageManager,
|
||||
IPackagingSourceManager packagingSourceManager,
|
||||
INotifier notifier) {
|
||||
INotifier notifier,
|
||||
IOrchardServices services) {
|
||||
_packageManager = packageManager;
|
||||
_packagingSourceManager = packagingSourceManager;
|
||||
_notifier = notifier;
|
||||
Services = services;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ActionResult Sources() {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list sources")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View(new PackagingSourcesViewModel {
|
||||
Sources = _packagingSourceManager.GetSources(),
|
||||
});
|
||||
}
|
||||
|
||||
public ActionResult Remove(int id) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove sources")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_packagingSourceManager.RemoveSource(id);
|
||||
_notifier.Information(T("The feed has been removed successfully."));
|
||||
return RedirectToAction("Sources");
|
||||
}
|
||||
|
||||
public ActionResult AddSource() {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View(new PackagingAddSourceViewModel());
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult AddSource(string url) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
try {
|
||||
if (!String.IsNullOrEmpty(url)) {
|
||||
if (!url.StartsWith("http")) {
|
||||
@@ -96,6 +112,9 @@ namespace Orchard.Packaging.Controllers {
|
||||
}
|
||||
|
||||
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 sources = selectedSource != null
|
||||
@@ -123,6 +142,9 @@ namespace Orchard.Packaging.Controllers {
|
||||
}
|
||||
|
||||
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 sources = selectedSource != null
|
||||
@@ -138,6 +160,9 @@ namespace Orchard.Packaging.Controllers {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (source == null) {
|
||||
|
@@ -8,6 +8,7 @@ using Orchard.Environment.Extensions;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Packaging.Services;
|
||||
using Orchard.Security;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Notify;
|
||||
@@ -25,40 +26,61 @@ namespace Orchard.Packaging.Controllers {
|
||||
public PackagingServicesController(
|
||||
IPackageManager packageManager,
|
||||
INotifier notifier,
|
||||
IAppDataFolderRoot appDataFolderRoot) {
|
||||
IAppDataFolderRoot appDataFolderRoot,
|
||||
IOrchardServices services) {
|
||||
_packageManager = packageManager;
|
||||
_notifier = notifier;
|
||||
_appDataFolderRoot = appDataFolderRoot;
|
||||
Services = services;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public IOrchardServices Services { get; set; }
|
||||
|
||||
public ActionResult AddTheme(string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add themes")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("AddTheme")]
|
||||
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);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("RemoveTheme")]
|
||||
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);
|
||||
}
|
||||
|
||||
public ActionResult AddModule(string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("AddModule")]
|
||||
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);
|
||||
}
|
||||
|
||||
public ActionResult InstallPackage(string returnUrl, string retryUrl) {
|
||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to install packages")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
try {
|
||||
if (Request.Files != null &&
|
||||
Request.Files.Count > 0 &&
|
||||
@@ -90,6 +112,9 @@ namespace Orchard.Packaging.Controllers {
|
||||
}
|
||||
|
||||
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 {
|
||||
_packageManager.Uninstall(id, HostingEnvironment.MapPath("~/"));
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Core.Common.Services;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.PublishLater.Models;
|
||||
using Orchard.PublishLater.Services;
|
||||
using Orchard.PublishLater.ViewModels;
|
||||
@@ -58,22 +59,24 @@ namespace Orchard.PublishLater.Drivers {
|
||||
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) && !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) {
|
||||
DateTime scheduled;
|
||||
string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime);
|
||||
if (Services.WorkContext.Resolve<IHttpContextAccessor>().Current().Request.Form["submit.Save"] == "submit.PublishLater") {
|
||||
if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) && !string.IsNullOrWhiteSpace(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
|
||||
if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) {
|
||||
model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime();
|
||||
_publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value);
|
||||
// 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)) {
|
||||
model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime();
|
||||
_publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value);
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
|
||||
}
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
|
||||
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 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",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
|
||||
|
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<!-- edit shape just get default placement -->
|
||||
<!-- 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 -->
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_PublishLater_Metadata_SummaryAdmin="Meta:1"/>
|
||||
|
@@ -6,9 +6,25 @@ html.dyn input.hinted {
|
||||
color:#ccc;
|
||||
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 {
|
||||
width:49%;
|
||||
width:39%;
|
||||
}
|
||||
input#PublishLater_ScheduledPublishTime {
|
||||
width:43%;
|
||||
}
|
||||
width:33%;
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
@Html.EditorFor(m => m.ScheduledPublishDate)
|
||||
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("ScheduledPublishTime")">@T("Time")</label>
|
||||
@Html.EditorFor(m => m.ScheduledPublishTime)
|
||||
<button type="submit" name="submit.Save" value="submit.PublishLater">@T("Publish Later")</button>
|
||||
</fieldset>
|
||||
@using(Script.Foot()) {
|
||||
<script type="text/javascript">
|
||||
|
@@ -15,19 +15,24 @@ using Orchard.Collections;
|
||||
using Orchard.Themes;
|
||||
|
||||
namespace Orchard.Search.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
[ValidateInput(false), Themed]
|
||||
public class SearchController : Controller {
|
||||
private readonly ISearchService _searchService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ISiteService _siteService;
|
||||
|
||||
public SearchController(
|
||||
IOrchardServices services,
|
||||
ISearchService searchService,
|
||||
IContentManager contentManager,
|
||||
ISearchService searchService,
|
||||
IContentManager contentManager,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
Services = services;
|
||||
_searchService = searchService;
|
||||
_contentManager = contentManager;
|
||||
_siteService = siteService;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
@@ -39,7 +44,8 @@ namespace Orchard.Search.Controllers {
|
||||
public ILogger Logger { 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;
|
||||
|
||||
IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { });
|
||||
|
@@ -7,17 +7,12 @@
|
||||
Model.ContentItems.Classes.Add("search-results");
|
||||
}
|
||||
<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 (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 {
|
||||
<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) {
|
||||
|
@@ -8,6 +8,7 @@ using Orchard.Commands.Builtin;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.Core.Settings.Models;
|
||||
using Orchard.Data.Migration.Interpreters;
|
||||
using Orchard.Data.Providers;
|
||||
using Orchard.Data.Migration;
|
||||
@@ -172,6 +173,11 @@ namespace Orchard.Setup {
|
||||
get { return ResourceDebugMode.FromAppSetting; }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public int PageSize {
|
||||
get { return SiteSettingsPartRecord.DefaultPageSize; }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,23 +4,28 @@ using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Tags.Services;
|
||||
using Orchard.Tags.ViewModels;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Tags.Controllers {
|
||||
[ValidateInput(false), Themed]
|
||||
public class HomeController : Controller {
|
||||
private readonly ITagService _tagService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly dynamic _shapeFactory;
|
||||
|
||||
public HomeController(
|
||||
ITagService tagService,
|
||||
IContentManager contentManager,
|
||||
ITagService tagService,
|
||||
IContentManager contentManager,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
_tagService = tagService;
|
||||
_contentManager = contentManager;
|
||||
_siteService = siteService;
|
||||
_shapeFactory = shapeFactory;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
@@ -34,21 +39,26 @@ namespace Orchard.Tags.Controllers {
|
||||
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);
|
||||
|
||||
if (tag == null) {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
var list = _shapeFactory.List();
|
||||
foreach (var taggedContentItem in _tagService.GetTaggedContentItems(tag.Id)) {
|
||||
list.Add(_contentManager.BuildDisplay(taggedContentItem, "Summary"));
|
||||
}
|
||||
var taggedItems = _tagService.GetTaggedContentItems(tag.Id, pager.GetStartIndex(), pager.PageSize)
|
||||
.Select(item => _contentManager.BuildDisplay(item, "Summary"));
|
||||
|
||||
var list = _shapeFactory.List();
|
||||
list.AddRange(taggedItems);
|
||||
|
||||
var totalItemCount = _tagService.GetTaggedContentItemCount(tag.Id);
|
||||
var viewModel = new TagsSearchViewModel {
|
||||
TagName = tag.TagName,
|
||||
List = list
|
||||
List = list,
|
||||
Pager = _shapeFactory.Pager(pager).TotalItemCount(totalItemCount)
|
||||
};
|
||||
|
||||
return View(viewModel);
|
||||
|
@@ -9,6 +9,10 @@ namespace Orchard.Tags.Services {
|
||||
TagRecord GetTagByName(string tagName);
|
||||
IEnumerable<IContent> GetTaggedContentItems(int tagId);
|
||||
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);
|
||||
|
||||
|
@@ -119,6 +119,27 @@ namespace Orchard.Tags.Services {
|
||||
.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) {
|
||||
var tagRecord = GetTagByName(tagName);
|
||||
var tagsContentItems = new ContentTagRecord { TagsPartRecord = tagsPartRecord, TagRecord = tagRecord };
|
||||
|
@@ -2,5 +2,6 @@
|
||||
public class TagsSearchViewModel {
|
||||
public string TagName { get; set; }
|
||||
public dynamic List { get; set; }
|
||||
public dynamic Pager { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,10 @@
|
||||
@model Orchard.Tags.ViewModels.TagsSearchViewModel
|
||||
|
||||
@{
|
||||
Html.AddTitleParts(T("Tags").ToString());
|
||||
Html.AddTitleParts(T("Contents tagged with {0}", Model.TagName).ToString());
|
||||
Model.List.Classes.Add("tagged-posts");
|
||||
Model.List.Classes.Add("content-items");
|
||||
}
|
||||
|
||||
<h1 class="page-title">@T("Contents tagged with <span>{0}</span>", Model.TagName)</h1>
|
||||
@Display(Model.List)
|
||||
@Display(Model.Pager)
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
@@ -27,8 +28,16 @@ namespace Orchard.Widgets.Drivers {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
protected override DriverResult Editor(LayerPart layerPart, dynamic shapeHelper) {
|
||||
return ContentShape("Parts_Widgets_LayerPart",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.LayerPart", Model: layerPart, Prefix: Prefix));
|
||||
var results = new List<DriverResult> {
|
||||
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) {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using JetBrains.Annotations;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Widgets.Models;
|
||||
@@ -18,8 +19,16 @@ namespace Orchard.Widgets.Drivers {
|
||||
widgetPart.AvailableZones = _widgetsService.GetZones();
|
||||
widgetPart.AvailableLayers = _widgetsService.GetLayers();
|
||||
|
||||
return ContentShape("Parts_Widgets_WidgetPart",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Widgets.WidgetPart", Model: widgetPart, Prefix: Prefix));
|
||||
var results = new List<DriverResult> {
|
||||
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) {
|
||||
|
@@ -130,6 +130,9 @@
|
||||
<Content Include="Views\EditorTemplates\Parts.Widgets.LayerPart.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts.Widgets.WidgetPart.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Widget.DeleteButton.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.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.
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<Placement>
|
||||
<Place Widget_DeleteButton="Sidebar:25"/>
|
||||
<Place Parts_Widgets_LayerPart="Content:1"/>
|
||||
<Place Parts_Widgets_WidgetPart="Content:1"/>
|
||||
<Place Parts_Widgets_WidegetBagPart="Content:5"/>
|
||||
|
@@ -2,8 +2,4 @@
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
@Display(Model)
|
||||
|
||||
<fieldset>
|
||||
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
|
||||
</fieldset>
|
||||
}
|
@@ -2,8 +2,4 @@
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
@Display(Model)
|
||||
|
||||
<fieldset>
|
||||
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
|
||||
</fieldset>
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
<fieldset class="delete-button">
|
||||
<button type="submit" name="submit.Delete" value="@T("Delete")">@T("Delete")</button>
|
||||
</fieldset>
|
@@ -732,7 +732,6 @@ table.items th, table.items td {
|
||||
border-spacing:0px;
|
||||
display:table-cell;
|
||||
padding:8px 12px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
/* Content item lists
|
||||
@@ -748,6 +747,7 @@ table.items th, table.items td {
|
||||
margin:0;
|
||||
overflow:hidden;
|
||||
padding:0 1.4em .8em;
|
||||
border-bottom:1px solid #eaeaea;
|
||||
}
|
||||
.contentItems li.last {
|
||||
border-bottom:none;
|
||||
@@ -859,51 +859,28 @@ table.items th, table.items td {
|
||||
}
|
||||
/* 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 {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
fieldset.publish-button {
|
||||
fieldset.publish-button, fieldset.delete-button, fieldset.save-button {
|
||||
clear:none;
|
||||
float:left;
|
||||
}
|
||||
fieldset.save-button {
|
||||
clear:left;
|
||||
}
|
||||
fieldset.publish-button {
|
||||
margin: 0 12px;
|
||||
padding: 0 12px;
|
||||
border-left:1px solid #ccc;
|
||||
}
|
||||
fieldset.save-button {
|
||||
clear:none;
|
||||
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;
|
||||
fieldset.delete-button {
|
||||
margin: 0 0 0 12px;
|
||||
}
|
||||
|
||||
|
||||
/* Fields
|
||||
***************************************************************/
|
||||
/* TextField */
|
||||
|
Reference in New Issue
Block a user