mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-22 03:37:25 +08:00
Refactoring Orchard.Comments
--HG-- branch : 1.x extra : rebase_source : 53cad738eb99ac7e2ac909821d4246c542284e9b
This commit is contained in:
@@ -19,24 +19,26 @@ namespace Orchard.Comments.Controllers {
|
||||
using Orchard.Settings;
|
||||
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller {
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
private readonly ICommentService _commentService;
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices services,
|
||||
ICommentService commentService,
|
||||
IOrchardServices orchardServices,
|
||||
ICommentService commentService,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
_orchardServices = orchardServices;
|
||||
_commentService = commentService;
|
||||
_siteService = siteService;
|
||||
Services = services;
|
||||
_contentManager = _orchardServices.ContentManager;
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
Shape = shapeFactory;
|
||||
}
|
||||
|
||||
public IOrchardServices Services { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
dynamic Shape { get; set; }
|
||||
@@ -72,7 +74,7 @@ namespace Orchard.Comments.Controllers {
|
||||
.OrderByDescending<CommentPartRecord>(cpr => cpr.CommentDateUtc)
|
||||
.Slice(pager.GetStartIndex(), pager.PageSize)
|
||||
.ToList()
|
||||
.Select(comment => CreateCommentEntry(comment.Record));
|
||||
.Select(comment => CreateCommentEntry(comment));
|
||||
|
||||
var model = new CommentsIndexViewModel {
|
||||
Comments = entries.ToList(),
|
||||
@@ -94,7 +96,7 @@ namespace Orchard.Comments.Controllers {
|
||||
case CommentIndexBulkAction.None:
|
||||
break;
|
||||
case CommentIndexBulkAction.MarkAsSpam:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
//TODO: Transaction
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -102,7 +104,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentIndexBulkAction.Unapprove:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
//TODO: Transaction
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -110,7 +112,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentIndexBulkAction.Approve:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
//TODO: Transaction
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -118,7 +120,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentIndexBulkAction.Delete:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -156,7 +158,7 @@ namespace Orchard.Comments.Controllers {
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
var entries = comments.List().Select(comment => CreateCommentEntry(comment.Record)).ToList();
|
||||
var entries = comments.List().Select(comment => CreateCommentEntry(comment)).ToList();
|
||||
var model = new CommentsDetailsViewModel {
|
||||
Comments = entries,
|
||||
Options = options,
|
||||
@@ -178,7 +180,7 @@ namespace Orchard.Comments.Controllers {
|
||||
case CommentDetailsBulkAction.None:
|
||||
break;
|
||||
case CommentDetailsBulkAction.MarkAsSpam:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
//TODO: Transaction
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -186,7 +188,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentDetailsBulkAction.Unapprove:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -194,7 +196,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentDetailsBulkAction.Approve:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't moderate comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -202,7 +204,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
break;
|
||||
case CommentDetailsBulkAction.Delete:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
foreach (CommentEntry entry in checkedEntries) {
|
||||
@@ -219,7 +221,7 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Disable(int commentedItemId, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't disable comments")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't disable comments")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_commentService.DisableCommentsForCommentedContent(commentedItemId);
|
||||
@@ -228,47 +230,49 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Enable(int commentedItemId, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't enable comments")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't enable comments")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
|
||||
_commentService.EnableCommentsForCommentedContent(commentedItemId);
|
||||
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
|
||||
}
|
||||
|
||||
public ActionResult Edit(int id) {
|
||||
CommentPart commentPart = _commentService.GetComment(id);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
if (commentPart == null)
|
||||
return new HttpNotFoundResult();
|
||||
|
||||
var viewModel = new CommentsEditViewModel {
|
||||
CommentText = commentPart.Record.CommentText,
|
||||
Email = commentPart.Record.Email,
|
||||
Id = commentPart.Record.Id,
|
||||
Name = commentPart.Record.Author,
|
||||
SiteName = commentPart.Record.SiteName,
|
||||
Status = commentPart.Record.Status,
|
||||
};
|
||||
return View(viewModel);
|
||||
dynamic editorShape = _contentManager.BuildEditor(commentPart);
|
||||
return View(editorShape);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Edit(FormCollection input) {
|
||||
var viewModel = new CommentsEditViewModel();
|
||||
UpdateModel(viewModel);
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't edit comment")))
|
||||
public ActionResult Edit(int id, FormCollection input) {
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't edit comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_commentService.UpdateComment(viewModel.Id, viewModel.Name, viewModel.Email, viewModel.SiteName, viewModel.CommentText, viewModel.Status);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
|
||||
var editorShape = _contentManager.UpdateEditor(commentPart, this);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
foreach (var error in ModelState.Values.SelectMany(m => m.Errors).Select(e => e.ErrorMessage)) {
|
||||
_orchardServices.Notifier.Error(T(error));
|
||||
}
|
||||
|
||||
TempData["Comments.InvalidCommentEditorShape"] = editorShape;
|
||||
}
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Approve(int id, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't approve comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't approve comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var commentPart = _commentService.GetComment(id);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
if (commentPart == null)
|
||||
return new HttpNotFoundResult();
|
||||
|
||||
@@ -280,10 +284,10 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Unapprove(int id, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't unapprove comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't unapprove comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var commentPart = _commentService.GetComment(id);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
if (commentPart == null)
|
||||
return new HttpNotFoundResult();
|
||||
|
||||
@@ -295,10 +299,10 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult MarkAsSpam(int id, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't mark comment as spam")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't mark comment as spam")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var commentPart = _commentService.GetComment(id);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
if (commentPart == null)
|
||||
return new HttpNotFoundResult();
|
||||
|
||||
@@ -310,10 +314,10 @@ namespace Orchard.Comments.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Delete(int id, string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
if (!_orchardServices.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't delete comment")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var commentPart = _commentService.GetComment(id);
|
||||
var commentPart = _contentManager.Get<CommentPart>(id);
|
||||
if (commentPart == null)
|
||||
return new HttpNotFoundResult();
|
||||
|
||||
@@ -323,10 +327,10 @@ namespace Orchard.Comments.Controllers {
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("Details", new { id = commentedOn }));
|
||||
}
|
||||
|
||||
private CommentEntry CreateCommentEntry(CommentPartRecord commentPart) {
|
||||
private CommentEntry CreateCommentEntry(CommentPart item) {
|
||||
return new CommentEntry {
|
||||
Comment = commentPart,
|
||||
CommentedOn = _commentService.GetCommentedContent(commentPart.CommentedOn),
|
||||
Comment = item.Record,
|
||||
Shape = _contentManager.BuildDisplay(item, "SummaryAdmin"),
|
||||
IsChecked = false,
|
||||
};
|
||||
}
|
||||
@@ -343,5 +347,13 @@ namespace Orchard.Comments.Controllers {
|
||||
return !string.IsNullOrEmpty(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||
}
|
||||
|
||||
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
|
||||
ModelState.AddModelError(key, errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,69 +10,65 @@ using Orchard.Mvc.Extensions;
|
||||
using Orchard.UI.Notify;
|
||||
|
||||
namespace Orchard.Comments.Controllers {
|
||||
public class CommentController : Controller {
|
||||
public class CommentController : Controller, IUpdateModel {
|
||||
public IOrchardServices Services { get; set; }
|
||||
private readonly ICommentService _commentService;
|
||||
private readonly INotifier _notifier;
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public CommentController(IOrchardServices services, ICommentService commentService, INotifier notifier) {
|
||||
Services = services;
|
||||
_commentService = commentService;
|
||||
_notifier = notifier;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
[HttpPost, ValidateInput(false)]
|
||||
public ActionResult Create(string returnUrl) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.AddComment, T("Couldn't add comment")))
|
||||
return this.RedirectLocal(returnUrl, "~/");
|
||||
|
||||
var viewModel = new CommentsCreateViewModel();
|
||||
|
||||
TryUpdateModel(viewModel);
|
||||
|
||||
var context = new CreateCommentContext {
|
||||
Author = viewModel.Name,
|
||||
CommentText = viewModel.CommentText,
|
||||
Email = viewModel.Email,
|
||||
SiteName = viewModel.SiteName,
|
||||
CommentedOn = viewModel.CommentedOn
|
||||
};
|
||||
var comment = Services.ContentManager.New("Comment");
|
||||
|
||||
Services.ContentManager.Create(comment);
|
||||
var editorShape = Services.ContentManager.UpdateEditor(comment, this);
|
||||
|
||||
if (ModelState.IsValid) {
|
||||
if (!String.IsNullOrEmpty(context.SiteName) && !context.SiteName.StartsWith("http://") && !context.SiteName.StartsWith("https://")) {
|
||||
context.SiteName = "http://" + context.SiteName;
|
||||
}
|
||||
if (comment.Has<CommentPart>()) {
|
||||
var commentPart = comment.As<CommentPart>();
|
||||
|
||||
CommentPart commentPart = _commentService.CreateComment(context, Services.WorkContext.CurrentSite.As<CommentSettingsPart>().Record.ModerateComments);
|
||||
|
||||
if (commentPart.Record.Status == CommentStatus.Pending) {
|
||||
// if the user who submitted the comment has the right to moderate, don't make this comment moderated
|
||||
if (Services.Authorizer.Authorize(Permissions.ManageComments)) {
|
||||
commentPart.Record.Status = CommentStatus.Approved;
|
||||
}
|
||||
else {
|
||||
Services.Notifier.Information(T("Your comment will appear after the site administrator approves it."));
|
||||
if (commentPart.Status == CommentStatus.Pending) {
|
||||
// if the user who submitted the comment has the right to moderate, don't make this comment moderated
|
||||
if (Services.Authorizer.Authorize(Permissions.ManageComments)) {
|
||||
commentPart.Status = CommentStatus.Approved;
|
||||
}
|
||||
else {
|
||||
Services.Notifier.Information(T("Your comment will appear after the site administrator approves it."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach (var error in ModelState.Values.SelectMany(m => m.Errors).Select( e=> e.ErrorMessage)) {
|
||||
Services.TransactionManager.Cancel();
|
||||
|
||||
foreach (var error in ModelState.Values.SelectMany(m => m.Errors).Select(e => e.ErrorMessage)) {
|
||||
_notifier.Error(T(error));
|
||||
}
|
||||
}
|
||||
|
||||
if(!ModelState.IsValid) {
|
||||
TempData["CreateCommentContext.Name"] = context.Author;
|
||||
TempData["CreateCommentContext.CommentText"] = context.CommentText;
|
||||
TempData["CreateCommentContext.Email"] = context.Email;
|
||||
TempData["CreateCommentContext.SiteName"] = context.SiteName;
|
||||
TempData["Comments.InvalidCommentEditorShape"] = editorShape;
|
||||
}
|
||||
|
||||
return this.RedirectLocal(returnUrl, "~/");
|
||||
}
|
||||
|
||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
||||
}
|
||||
|
||||
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
|
||||
ModelState.AddModelError(key, errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,15 +4,84 @@ using JetBrains.Annotations;
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Comments.Services;
|
||||
|
||||
namespace Orchard.Comments.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class CommentPartDriver : ContentPartDriver<CommentPart> {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IClock _clock;
|
||||
private readonly ICommentService _commentService;
|
||||
|
||||
protected override string Prefix { get { return "Comments"; } }
|
||||
|
||||
public CommentPartDriver(IContentManager contentManager) {
|
||||
public Localizer T { get; set; }
|
||||
|
||||
public CommentPartDriver(
|
||||
IContentManager contentManager,
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IClock clock,
|
||||
ICommentService commentService) {
|
||||
_contentManager = contentManager;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_clock = clock;
|
||||
_commentService = commentService;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(CommentPart part, string displayType, dynamic shapeHelper) {
|
||||
return Combined(
|
||||
ContentShape("Parts_Comment", () => shapeHelper.Parts_Comment()),
|
||||
ContentShape("Parts_Comment_SummaryAdmin", () => shapeHelper.Parts_Comment_SummaryAdmin())
|
||||
);
|
||||
}
|
||||
|
||||
// GET
|
||||
protected override DriverResult Editor(CommentPart part, dynamic shapeHelper) {
|
||||
if (Orchard.UI.Admin.AdminFilter.IsApplied(_workContextAccessor.GetContext().HttpContext.Request.RequestContext)) {
|
||||
return ContentShape("Parts_Comment_AdminEdit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Comment.AdminEdit", Model: part, Prefix: Prefix));
|
||||
}
|
||||
else {
|
||||
return ContentShape("Parts_Comment_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Comment", Model: part, Prefix: Prefix));
|
||||
}
|
||||
}
|
||||
|
||||
// POST
|
||||
protected override DriverResult Editor(CommentPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
updater.TryUpdateModel(part, Prefix, null, null);
|
||||
var workContext = _workContextAccessor.GetContext();
|
||||
|
||||
part.CommentDateUtc = _clock.UtcNow;
|
||||
|
||||
if (!String.IsNullOrEmpty(part.SiteName) && !part.SiteName.StartsWith("http://") && !part.SiteName.StartsWith("https://")) {
|
||||
part.SiteName = "http://" + part.SiteName;
|
||||
}
|
||||
|
||||
// TODO: it's very bad how the corresponding user is stored. Needs revision.
|
||||
var currentUser = workContext.CurrentUser;
|
||||
part.UserName = (currentUser != null ? currentUser.UserName : null);
|
||||
|
||||
if (currentUser != null) part.Author = currentUser.UserName;
|
||||
|
||||
if (String.IsNullOrEmpty(part.Author)) updater.AddModelError("NameMissing", T("You didn't specify your name."));
|
||||
|
||||
// TODO: needs spam handling
|
||||
part.Status = workContext.CurrentSite.As<CommentSettingsPart>().ModerateComments ? CommentStatus.Pending : CommentStatus.Approved;
|
||||
|
||||
var commentedOn = _contentManager.Get<ICommonPart>(part.CommentedOn);
|
||||
if (commentedOn != null && commentedOn.Container != null) {
|
||||
part.CommentedOnContainer = commentedOn.Container.ContentItem.Id;
|
||||
}
|
||||
commentedOn.As<CommentsPart>().Record.CommentPartRecords.Add(part.Record);
|
||||
|
||||
return Editor(part, shapeHelper);
|
||||
}
|
||||
|
||||
protected override void Importing(CommentPart part, ContentManagement.Handlers.ImportContentContext context) {
|
||||
@@ -38,7 +107,7 @@ namespace Orchard.Comments.Drivers {
|
||||
|
||||
var status = context.Attribute(part.PartDefinition.Name, "Status");
|
||||
if (status != null) {
|
||||
part.Record.Status = (CommentStatus) Enum.Parse(typeof(CommentStatus), status);
|
||||
part.Record.Status = (CommentStatus)Enum.Parse(typeof(CommentStatus), status);
|
||||
}
|
||||
|
||||
var commentDate = context.Attribute(part.PartDefinition.Name, "CommentDateUtc");
|
||||
|
@@ -20,7 +20,6 @@ namespace Orchard.Comments.Drivers {
|
||||
Func<int> approvedCount = () => commentsForCommentedContent.Where(x => x.Status == CommentStatus.Approved).Count();
|
||||
|
||||
return Combined(
|
||||
|
||||
ContentShape("Parts_Comments_Count",
|
||||
() => shapeHelper.Parts_Comments_Count(CommentCount: approvedCount(), PendingCount: pendingCount())),
|
||||
ContentShape("Parts_Comments_Count_SummaryAdmin",
|
||||
|
@@ -4,14 +4,19 @@ using Orchard.Comments.Models;
|
||||
using Orchard.Comments.Services;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Comments.Drivers {
|
||||
[UsedImplicitly]
|
||||
public class CommentsPartDriver : ContentPartDriver<CommentsPart> {
|
||||
private readonly ICommentService _commentService;
|
||||
|
||||
public CommentsPartDriver(ICommentService commentService) {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public CommentsPartDriver(
|
||||
ICommentService commentService,
|
||||
IContentManager contentManager) {
|
||||
_commentService = commentService;
|
||||
_contentManager = contentManager;
|
||||
}
|
||||
|
||||
protected override DriverResult Display(CommentsPart part, string displayType, dynamic shapeHelper) {
|
||||
@@ -23,10 +28,25 @@ namespace Orchard.Comments.Drivers {
|
||||
Func<int> approvedCount = () => commentsForCommentedContent.Where(x => x.Status == CommentStatus.Approved).Count();
|
||||
|
||||
return Combined(
|
||||
ContentShape("Parts_Comments",
|
||||
() => shapeHelper.Parts_Comments()),
|
||||
ContentShape("Parts_ListOfComments",
|
||||
() => {
|
||||
var commentShapes = new List<dynamic>();
|
||||
foreach (var item in part.Comments) {
|
||||
commentShapes.Add(_contentManager.BuildDisplay(item.ContentItem, "Summary"));
|
||||
}
|
||||
|
||||
return shapeHelper.Parts_ListOfComments(CommentShapes: commentShapes);
|
||||
}),
|
||||
ContentShape("Parts_CommentForm",
|
||||
() => {
|
||||
var newComment = _contentManager.New("Comment");
|
||||
if (newComment.Has<CommentPart>()) newComment.As<CommentPart>().CommentedOn = part.Id;
|
||||
var editorShape = _contentManager.BuildEditor(newComment);
|
||||
|
||||
return shapeHelper.Parts_CommentForm(EditorShape: editorShape);
|
||||
}),
|
||||
ContentShape("Parts_Comments_Count",
|
||||
() => shapeHelper.Parts_Comments_Count(CommentCount: approvedCount(), PendingCount: pendingCount())),
|
||||
() => shapeHelper.Parts_Comments_Count(CommentCount: approvedCount(), PendingCount: pendingCount())),
|
||||
ContentShape("Parts_Comments_Count_SummaryAdmin",
|
||||
() => shapeHelper.Parts_Comments_Count_SummaryAdmin(CommentCount: approvedCount(), PendingCount: pendingCount()))
|
||||
);
|
||||
|
@@ -2,12 +2,29 @@ using JetBrains.Annotations;
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Comments.Handlers {
|
||||
[UsedImplicitly]
|
||||
public class CommentPartHandler : ContentHandler {
|
||||
public CommentPartHandler(IRepository<CommentPartRecord> commentsRepository) {
|
||||
public CommentPartHandler(
|
||||
IRepository<CommentPartRecord> commentsRepository,
|
||||
IContentManager contentManager) {
|
||||
|
||||
Filters.Add(StorageFilter.For(commentsRepository));
|
||||
|
||||
OnLoading<CommentPart>((context, comment) => {
|
||||
comment.CommentedOnContentItemField.Loader(
|
||||
item => contentManager.Get(comment.CommentedOn)
|
||||
);
|
||||
|
||||
comment.CommentedOnContentItemMetadataField.Loader(
|
||||
item => contentManager.GetItemMetadata(comment.CommentedOnContentItem)
|
||||
);
|
||||
});
|
||||
|
||||
OnIndexing<CommentPart>((context, commentPart) => context.DocumentIndex
|
||||
.Add("commentText", commentPart.Record.CommentText));
|
||||
}
|
||||
}
|
||||
}
|
@@ -17,19 +17,19 @@ namespace Orchard.Comments.Handlers {
|
||||
|
||||
Filters.Add(StorageFilter.For(commentsRepository));
|
||||
|
||||
OnInitializing<CommentsPart>((ctx, x) => {
|
||||
x.CommentsActive = true;
|
||||
x.CommentsShown = true;
|
||||
x.Comments = new List<CommentPart>();
|
||||
OnInitializing<CommentsPart>((ctx, part) => {
|
||||
part.CommentsActive = true;
|
||||
part.CommentsShown = true;
|
||||
part.Comments = new List<CommentPart>();
|
||||
});
|
||||
|
||||
OnLoading<CommentsPart>((context, comments) => {
|
||||
comments._comments.Loader(list => contentManager
|
||||
comments.CommentsField.Loader(list => contentManager
|
||||
.Query<CommentPart, CommentPartRecord>()
|
||||
.Where(x => x.CommentsPartRecord == context.ContentItem.As<CommentsPart>().Record && x.Status == CommentStatus.Approved)
|
||||
.List().ToList());
|
||||
|
||||
comments._pendingComments.Loader(list => contentManager
|
||||
comments.PendingCommentsField.Loader(list => contentManager
|
||||
.Query<CommentPart, CommentPartRecord>()
|
||||
.Where(x => x.CommentsPartRecord == context.ContentItem.As<CommentsPart>().Record && x.Status == CommentStatus.Pending)
|
||||
.List().ToList());
|
||||
|
@@ -33,8 +33,6 @@ namespace Orchard.Comments {
|
||||
.ContentPartRecord()
|
||||
.Column<bool>("ModerateComments")
|
||||
.Column<bool>("EnableSpamProtection")
|
||||
.Column<string>("AkismetKey")
|
||||
.Column<string>("AkismetUrl")
|
||||
);
|
||||
|
||||
SchemaBuilder.CreateTable("CommentsPartRecord", table => table
|
||||
@@ -46,7 +44,10 @@ namespace Orchard.Comments {
|
||||
ContentDefinitionManager.AlterTypeDefinition("Comment",
|
||||
cfg => cfg
|
||||
.WithPart("CommentPart")
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("CommonPart",
|
||||
p => p
|
||||
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
||||
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
||||
.WithPart("IdentityPart")
|
||||
);
|
||||
|
||||
@@ -84,5 +85,25 @@ namespace Orchard.Comments {
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
public int UpdateFrom3() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("Comment",
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart",
|
||||
p => p
|
||||
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
||||
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
||||
);
|
||||
|
||||
SchemaBuilder.AlterTable("CommentSettingsPartRecord", table => table
|
||||
.DropColumn("AkismetKey")
|
||||
);
|
||||
|
||||
SchemaBuilder.AlterTable("CommentSettingsPartRecord", table => table
|
||||
.DropColumn("AkismetUrl")
|
||||
);
|
||||
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,76 @@
|
||||
using Orchard.ContentManagement;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel;
|
||||
using Orchard.ContentManagement.Utilities;
|
||||
|
||||
namespace Orchard.Comments.Models {
|
||||
public class CommentPart : ContentPart<CommentPartRecord> {
|
||||
private readonly LazyField<ContentItem> _commentedOnContentItem = new LazyField<ContentItem>();
|
||||
private readonly LazyField<ContentItemMetadata> _commentedOnContentItemMetadata = new LazyField<ContentItemMetadata>();
|
||||
|
||||
public LazyField<ContentItem> CommentedOnContentItemField { get { return _commentedOnContentItem; } }
|
||||
public LazyField<ContentItemMetadata> CommentedOnContentItemMetadataField { get { return _commentedOnContentItemMetadata; } }
|
||||
|
||||
public string Author {
|
||||
get { return Record.Author; }
|
||||
set { Record.Author = value; }
|
||||
}
|
||||
|
||||
[StringLength(245)]
|
||||
[DisplayName("Site")]
|
||||
[RegularExpression(@"^(http(s)?://)?([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}[\S]+$", ErrorMessage = "Invalid url")]
|
||||
public string SiteName {
|
||||
get { return Record.SiteName; }
|
||||
set { Record.SiteName = value; }
|
||||
}
|
||||
|
||||
public string UserName {
|
||||
get { return Record.UserName; }
|
||||
set { Record.UserName = value; }
|
||||
}
|
||||
|
||||
[RegularExpression(@"^[^@\s]+@[^@\s]+$", ErrorMessage = "Invalid Email")]
|
||||
[StringLength(255)]
|
||||
public string Email {
|
||||
get { return Record.Email; }
|
||||
set { Record.Email = value; }
|
||||
}
|
||||
|
||||
public CommentStatus Status {
|
||||
get { return Record.Status; }
|
||||
set { Record.Status = value; }
|
||||
}
|
||||
|
||||
public DateTime? CommentDateUtc {
|
||||
get { return Record.CommentDateUtc; }
|
||||
set { Record.CommentDateUtc = value; }
|
||||
}
|
||||
|
||||
[Required, DisplayName("Comment")]
|
||||
public string CommentText {
|
||||
get { return Record.CommentText; }
|
||||
set { Record.CommentText = value; }
|
||||
}
|
||||
|
||||
public int CommentedOn {
|
||||
get { return Record.CommentedOn; }
|
||||
set { Record.CommentedOn = value; }
|
||||
}
|
||||
|
||||
public ContentItem CommentedOnContentItem {
|
||||
get { return _commentedOnContentItem.Value; }
|
||||
set { _commentedOnContentItem.Value = value; }
|
||||
}
|
||||
|
||||
public ContentItemMetadata CommentedOnContentItemMetadata {
|
||||
get { return _commentedOnContentItemMetadata.Value; }
|
||||
set { _commentedOnContentItemMetadata.Value = value; }
|
||||
}
|
||||
|
||||
public int CommentedOnContainer {
|
||||
get { return Record.CommentedOnContainer; }
|
||||
set { Record.CommentedOnContainer = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,7 +4,5 @@ namespace Orchard.Comments.Models {
|
||||
public class CommentSettingsPartRecord : ContentPartRecord {
|
||||
public virtual bool ModerateComments { get; set; }
|
||||
public virtual bool EnableSpamProtection { get; set; }
|
||||
public virtual string AkismetKey { get; set; }
|
||||
public virtual string AkismetUrl { get; set; }
|
||||
}
|
||||
}
|
@@ -4,16 +4,21 @@ using Orchard.ContentManagement.Utilities;
|
||||
|
||||
namespace Orchard.Comments.Models {
|
||||
public class CommentsPart : ContentPart<CommentsPartRecord> {
|
||||
public CommentsPart() {
|
||||
Comments = new List<CommentPart>();
|
||||
PendingComments = new List<CommentPart>();
|
||||
private readonly LazyField<IList<CommentPart>> _comments = new LazyField<IList<CommentPart>>();
|
||||
private readonly LazyField<IList<CommentPart>> _pendingComments = new LazyField<IList<CommentPart>>();
|
||||
|
||||
public LazyField<IList<CommentPart>> CommentsField { get { return _comments; } }
|
||||
public LazyField<IList<CommentPart>> PendingCommentsField { get { return _pendingComments; } }
|
||||
|
||||
public IList<CommentPart> Comments {
|
||||
get { return _comments.Value; }
|
||||
set { _comments.Value = value; }
|
||||
}
|
||||
|
||||
public IList<CommentPart> PendingComments {
|
||||
get { return _pendingComments.Value; }
|
||||
set { _pendingComments.Value = value; }
|
||||
}
|
||||
|
||||
public readonly LazyField<IList<CommentPart>> _comments = new LazyField<IList<CommentPart>>();
|
||||
public readonly LazyField<IList<CommentPart>> _pendingComments = new LazyField<IList<CommentPart>>();
|
||||
|
||||
public IList<CommentPart> Comments { get { return _comments.Value; } set { _comments.Value = value; } }
|
||||
public IList<CommentPart> PendingComments { get { return _pendingComments.Value; } set { _pendingComments.Value = value; } }
|
||||
|
||||
public bool CommentsShown {
|
||||
get { return Record.CommentsShown; }
|
||||
|
@@ -21,6 +21,10 @@
|
||||
</UpgradeBackupLocation>
|
||||
<TargetFrameworkProfile />
|
||||
<UseIISExpress>false</UseIISExpress>
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -42,11 +46,6 @@
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Joel.Net.Akismet, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\lib\joel.net.akismet\Joel.Net.Akismet.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
@@ -97,14 +96,12 @@
|
||||
<Compile Include="Services\CommentService.cs" />
|
||||
<Compile Include="Services\CommentValidator.cs" />
|
||||
<Compile Include="Services\ICommentValidator.cs" />
|
||||
<Compile Include="ViewModels\CommentsCreateViewModel.cs" />
|
||||
<Compile Include="ViewModels\CommentsDetailsViewModel.cs" />
|
||||
<Compile Include="ViewModels\CommentsEditViewModel.cs" />
|
||||
<Compile Include="ViewModels\CommentsIndexViewModel.cs" />
|
||||
<Compile Include="ViewModels\EditCommentsViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Release notes.txt" />
|
||||
<Content Include="Styles\images\menu.comments.png" />
|
||||
<Content Include="Styles\menu.comments-admin.css" />
|
||||
<Content Include="Styles\orchard-comments-admin.css" />
|
||||
@@ -124,12 +121,12 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Admin\Edit.cshtml" />
|
||||
<Content Include="Views\Admin\Index.cshtml" />
|
||||
<Content Include="Views\Parts.Comments.cshtml" />
|
||||
<Content Include="Views\Parts.CommentForm.cshtml" />
|
||||
<Content Include="Views\Parts.Comments.Count.cshtml" />
|
||||
<Content Include="Views\Parts.Comments.Count.SummaryAdmin.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts.Comments.Comments.cshtml" />
|
||||
<Content Include="Views\EditorTemplates\Parts.Comments.SiteSettings.cshtml" />
|
||||
<Content Include="Views\ListOfComments.cshtml" />
|
||||
<Content Include="Views\Parts.ListOfComments.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Placement.info">
|
||||
@@ -150,6 +147,17 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Views\CommentMetadata.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Parts.Comment.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Parts.Comment.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\EditorTemplates\Parts.Comment.AdminEdit.cshtml" />
|
||||
<Content Include="Views\Content-Comment.SummaryAdmin.cshtml" />
|
||||
<None Include="Views\Parts.Comment.SummaryAdmin.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@@ -1,21 +1,31 @@
|
||||
<Placement>
|
||||
<!-- available display shapes -->
|
||||
<!--
|
||||
<!-- available display shapes -->
|
||||
<!--
|
||||
Parts_Comments
|
||||
Parts_Comments_Count
|
||||
Parts_Comments_Count_SummaryAdmin
|
||||
-->
|
||||
<!-- widget and edit shapes just get default placement -->
|
||||
<!-- edit "shapes" -->
|
||||
<Place Parts_Comments_Enable="Content:10"/>
|
||||
<Place Parts_Comments_SiteSettings="Content:10"/>
|
||||
<Match DisplayType="Detail">
|
||||
<Place Parts_Comments="Content:10" />
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_Comments_Count="Meta:5" />
|
||||
</Match>
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_Comments_Count_SummaryAdmin="Meta:4" />
|
||||
</Match>
|
||||
<!-- widget and edit shapes just get default placement -->
|
||||
<!-- edit "shapes" -->
|
||||
|
||||
<Place Parts_Comments_Enable="Content:10"/>
|
||||
<Place Parts_Comments_SiteSettings="Content:10"/>
|
||||
<Place Parts_Comment_Edit="Content:10"/>
|
||||
<Place Parts_Comment_AdminEdit="Content:10"/>
|
||||
|
||||
<Match ContentType="Comment">
|
||||
<Place Content_SaveButton="-"/><!--Show default save button only on admin-->
|
||||
</Match>
|
||||
<Match DisplayType="Detail">
|
||||
<Place Parts_ListOfComments="Content:10" />
|
||||
<Place Parts_CommentForm="Content:10" />
|
||||
</Match>
|
||||
<Match DisplayType="Summary">
|
||||
<Place Parts_Comments_Count="Meta:5"
|
||||
Parts_Comment="Content:10" />
|
||||
</Match>
|
||||
<Match DisplayType="SummaryAdmin">
|
||||
<Place Parts_Comment_SummaryAdmin="Content:10"
|
||||
Parts_Comments_Count_SummaryAdmin="Meta:4" />
|
||||
</Match>
|
||||
</Placement>
|
||||
|
13
src/Orchard.Web/Modules/Orchard.Comments/Release notes.txt
Normal file
13
src/Orchard.Web/Modules/Orchard.Comments/Release notes.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
==== RELEASE NOTES ====
|
||||
|
||||
|
||||
== New features ==
|
||||
- Comment display and edit shapes are dynamically built, so parts can be attached to comments and placement can be configured (also for admin)
|
||||
|
||||
== Breaking changes ==
|
||||
- Css ids of the comment form's fields have changed
|
||||
TODO: list old ids and new one for migration steps. Changed because of usage of Html.FieldIdFor(...)
|
||||
|
||||
- CommentService (and ICommentService) has multiple breaking changes: CreateComment and UpdateComment was removed, use ContentManager methods instead
|
||||
- Comments used plenty of static viewmodels; some very completely removed, some changed adapting to comment shape building; if you've overridden any comment
|
||||
shapes, check them
|
@@ -32,26 +32,18 @@ namespace Orchard.Comments.Services {
|
||||
}
|
||||
|
||||
public IContentQuery<CommentPart, CommentPartRecord> GetComments(CommentStatus status) {
|
||||
return _orchardServices.ContentManager
|
||||
.Query<CommentPart, CommentPartRecord>()
|
||||
return GetComments()
|
||||
.Where(c => c.Status == status);
|
||||
}
|
||||
|
||||
public IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id) {
|
||||
return _orchardServices.ContentManager
|
||||
.Query<CommentPart, CommentPartRecord>()
|
||||
return GetComments()
|
||||
.Where(c => c.CommentedOn == id || c.CommentedOnContainer == id);
|
||||
}
|
||||
|
||||
public IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id, CommentStatus status) {
|
||||
return _orchardServices.ContentManager
|
||||
.Query<CommentPart, CommentPartRecord>()
|
||||
.Where(c => c.CommentedOn == id || c.CommentedOnContainer == id)
|
||||
.Where(ctx => ctx.Status == status);
|
||||
}
|
||||
|
||||
public CommentPart GetComment(int id) {
|
||||
return _orchardServices.ContentManager.Get<CommentPart>(id);
|
||||
return GetCommentsForCommentedContent(id)
|
||||
.Where(c => c.Status == status);
|
||||
}
|
||||
|
||||
public ContentItemMetadata GetDisplayForCommentedContent(int id) {
|
||||
@@ -68,47 +60,18 @@ namespace Orchard.Comments.Services {
|
||||
return result;
|
||||
}
|
||||
|
||||
public CommentPart CreateComment(CreateCommentContext context, bool moderateComments) {
|
||||
return _orchardServices.ContentManager.Create<CommentPart>("Comment", comment => {
|
||||
comment.Record.Author = context.Author;
|
||||
comment.Record.CommentDateUtc = _clock.UtcNow;
|
||||
comment.Record.CommentText = context.CommentText;
|
||||
comment.Record.Email = context.Email;
|
||||
comment.Record.SiteName = context.SiteName;
|
||||
comment.Record.UserName = (_orchardServices.WorkContext.CurrentUser != null ? _orchardServices.WorkContext.CurrentUser.UserName : null);
|
||||
comment.Record.CommentedOn = context.CommentedOn;
|
||||
comment.Record.Status = _commentValidator.ValidateComment(comment)
|
||||
? moderateComments ? CommentStatus.Pending : CommentStatus.Approved
|
||||
: CommentStatus.Spam;
|
||||
var commentedOn = _orchardServices.ContentManager.Get<ICommonPart>(comment.Record.CommentedOn);
|
||||
if (commentedOn != null && commentedOn.Container != null) {
|
||||
comment.Record.CommentedOnContainer = commentedOn.Container.ContentItem.Id;
|
||||
}
|
||||
commentedOn.As<CommentsPart>().Record.CommentPartRecords.Add(comment.Record);
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateComment(int id, string name, string email, string siteName, string commentText, CommentStatus status) {
|
||||
CommentPart commentPart = GetComment(id);
|
||||
commentPart.Record.Author = name;
|
||||
commentPart.Record.Email = email;
|
||||
commentPart.Record.SiteName = siteName;
|
||||
commentPart.Record.CommentText = commentText;
|
||||
commentPart.Record.Status = status;
|
||||
}
|
||||
|
||||
public void ApproveComment(int commentId) {
|
||||
CommentPart commentPart = GetComment(commentId);
|
||||
var commentPart = GetCommentWithQueryHints(commentId);
|
||||
commentPart.Record.Status = CommentStatus.Approved;
|
||||
}
|
||||
|
||||
public void UnapproveComment(int commentId) {
|
||||
CommentPart commentPart = GetComment(commentId);
|
||||
var commentPart = GetCommentWithQueryHints(commentId);
|
||||
commentPart.Record.Status = CommentStatus.Pending;
|
||||
}
|
||||
|
||||
public void MarkCommentAsSpam(int commentId) {
|
||||
CommentPart commentPart = GetComment(commentId);
|
||||
var commentPart = GetCommentWithQueryHints(commentId);
|
||||
commentPart.Record.Status = CommentStatus.Spam;
|
||||
}
|
||||
|
||||
@@ -127,5 +90,9 @@ namespace Orchard.Comments.Services {
|
||||
public void EnableCommentsForCommentedContent(int id) {
|
||||
_orchardServices.ContentManager.Get<CommentsPart>(id, VersionOptions.Latest).CommentsActive = true;
|
||||
}
|
||||
|
||||
private CommentPart GetCommentWithQueryHints(int id) {
|
||||
return _orchardServices.ContentManager.Get<CommentPart>(id, VersionOptions.Latest, new QueryHints().ExpandParts<CommentPart>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,11 +7,8 @@ namespace Orchard.Comments.Services {
|
||||
IContentQuery<CommentPart, CommentPartRecord> GetComments(CommentStatus status);
|
||||
IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id);
|
||||
IContentQuery<CommentPart, CommentPartRecord> GetCommentsForCommentedContent(int id, CommentStatus status);
|
||||
CommentPart GetComment(int id);
|
||||
ContentItemMetadata GetDisplayForCommentedContent(int id);
|
||||
ContentItem GetCommentedContent(int id);
|
||||
CommentPart CreateComment(CreateCommentContext commentRecord, bool moderateComments);
|
||||
void UpdateComment(int id, string name, string email, string siteName, string commentText, CommentStatus status);
|
||||
void ApproveComment(int commentId);
|
||||
void UnapproveComment(int commentId);
|
||||
void MarkCommentAsSpam(int commentId);
|
||||
|
@@ -1,24 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Orchard.Comments.ViewModels {
|
||||
public class CommentsCreateViewModel {
|
||||
[Required]
|
||||
[StringLength(255)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[RegularExpression(@"^[^@\s]+@[^@\s]+$", ErrorMessage = "Invalid Email")]
|
||||
[StringLength(255)]
|
||||
public string Email { get; set; }
|
||||
|
||||
[StringLength(245)]
|
||||
[DisplayName("Site")]
|
||||
[RegularExpression(@"^(http(s)?://)?([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}[\S]+$", ErrorMessage = "Invalid url")]
|
||||
public string SiteName { get; set; }
|
||||
|
||||
[Required, DisplayName("Comment")]
|
||||
public string CommentText { get; set; }
|
||||
|
||||
public int CommentedOn { get; set; }
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
using Orchard.Comments.Models;
|
||||
|
||||
namespace Orchard.Comments.ViewModels {
|
||||
public class CommentsEditViewModel {
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string SiteName { get; set; }
|
||||
public string CommentText { get; set; }
|
||||
public CommentStatus Status { get; set; }
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Comments.ViewModels {
|
||||
public class CommentsIndexViewModel {
|
||||
@@ -9,9 +9,10 @@ namespace Orchard.Comments.ViewModels {
|
||||
public dynamic Pager { get; set; }
|
||||
}
|
||||
|
||||
[Bind(Exclude = "Shape")]
|
||||
public class CommentEntry {
|
||||
public CommentPartRecord Comment { get; set; }
|
||||
public ContentItem CommentedOn { get; set; }
|
||||
public dynamic Shape { get; set; }
|
||||
public bool IsChecked { get; set; }
|
||||
}
|
||||
|
||||
|
@@ -1,4 +0,0 @@
|
||||
namespace Orchard.Comments.ViewModels {
|
||||
public class EditCommentsViewModel {
|
||||
}
|
||||
}
|
@@ -1,46 +1,8 @@
|
||||
@model Orchard.Comments.ViewModels.CommentsEditViewModel
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Comments.Models;
|
||||
|
||||
@{ Layout.Title = T("Edit Comment").ToString(); }
|
||||
|
||||
@using(Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
<fieldset class="who">
|
||||
<div>
|
||||
<label for="Name">@T("Name")</label>
|
||||
<input id="Name" class="text" name="Name" type="text" value="@Model.Name" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="Email">@T("Email")</label>
|
||||
<input id="Email" class="text" name="Email" type="text" value="@Model.Email" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="SiteName">@T("Url")</label>
|
||||
<input id="SiteName" class="text" name="SiteName" type="text" value="@Model.SiteName" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="what">
|
||||
<div>
|
||||
<label for="CommentText">@T("Body")</label>
|
||||
<textarea id="CommentText" rows="10" cols="30" name="CommentText">@Model.CommentText</textarea>
|
||||
<input id="CommentId" name="Id" type="hidden" value="@Model.Id" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
@Html.RadioButton("Status", "Pending", (Model.Status == CommentStatus.Pending), new { id = "Status_Pending" })
|
||||
<label class="forcheckbox" for="Status_Pending">@T("Pending")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButton("Status", "Approved", (Model.Status == CommentStatus.Approved), new { id = "Status_Approved" })
|
||||
<label class="forcheckbox" for="Status_Approved">@T("Approved")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButton("Status", "Spam", (Model.Status == CommentStatus.Spam), new { id = "Status_Spam" })
|
||||
<label class="forcheckbox" for="Status_Spam">@T("Mark as spam")</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit">@T("Save")</button>
|
||||
</fieldset>
|
||||
@Display(Model);
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
@using Orchard.Comments.ViewModels;
|
||||
@using Orchard.Mvc.Html;
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@{
|
||||
Style.Require("Admin");
|
||||
Script.Require("ShapesBase");
|
||||
@@ -64,45 +65,7 @@
|
||||
<input type="hidden" value="@Model.Comments[commentIndex].Comment.Id" name="@Html.NameOf(m => m.Comments[commentIndex].Comment.Id)"/>
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Comments[commentIndex].IsChecked)"/>
|
||||
</td>
|
||||
<td>
|
||||
@if (commentEntry.Comment.Status == CommentStatus.Spam) { @T("Spam") }
|
||||
else if (commentEntry.Comment.Status == CommentStatus.Pending) { @T("Pending") }
|
||||
else { @T("Approved") }
|
||||
</td>
|
||||
<td>
|
||||
<div>@commentEntry.Comment.Author</div>
|
||||
@if (HasText(commentEntry.Comment.UserName) && commentEntry.Comment.Author != commentEntry.Comment.UserName) {
|
||||
<div class="authenticated-commenter-id">@commentEntry.Comment.UserName</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@* would ideally have permalinks for individual comments *@
|
||||
<p><a href="@Url.ItemDisplayUrl(commentEntry.CommentedOn)#comments"><time>@Display.DateTime(DateTimeUtc: commentEntry.Comment.CommentDateUtc.GetValueOrDefault())</time></a></p>
|
||||
@if (commentEntry.Comment.CommentText != null) {
|
||||
var ellipsized = Html.Ellipsize(commentEntry.Comment.CommentText, 500);
|
||||
var paragraphed = new HtmlString(ellipsized.ToHtmlString().Replace("\r\n", "</p><p>"));
|
||||
<p>@paragraphed</p>
|
||||
}
|
||||
else {
|
||||
@T("[Empty]")
|
||||
}
|
||||
</td>
|
||||
<td>@Html.ItemDisplayLink(commentEntry.CommentedOn)</td>
|
||||
<td>
|
||||
<div class="actions">
|
||||
@if (commentEntry.Comment.Status != CommentStatus.Spam) {
|
||||
<a href="@Url.Action("MarkAsSpam", new {commentEntry.Comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString()})" itemprop="RemoveUrl UnsafeUrl">@T("Spam")</a>@T(" | ")
|
||||
}
|
||||
@if (commentEntry.Comment.Status != CommentStatus.Approved) {
|
||||
<a href="@Url.Action("Approve", new {commentEntry.Comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString()})" itemprop="ApproveUrl UnsafeUrl">@T("Approve")</a>@T(" | ")
|
||||
}
|
||||
else {
|
||||
<a href="@Url.Action("Unapprove", new {commentEntry.Comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString()})" itemprop="UnapproveUrl UnsafeUrl">@T("Unapprove")</a>@T(" | ")
|
||||
}
|
||||
<a href="@Url.Action("Edit", new {commentEntry.Comment.Id})" title="@T("Edit")">@T("Edit")</a>@T(" | ")
|
||||
<a href="@Url.Action("Delete", new {commentEntry.Comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString()})" itemprop="RemoveUrl UnsafeUrl">@T("Delete")</a>
|
||||
</div>
|
||||
</td>
|
||||
@Display(commentEntry.Shape)
|
||||
</tr>
|
||||
commentIndex = commentIndex + 1;
|
||||
}
|
||||
|
@@ -1,13 +1,5 @@
|
||||
@*
|
||||
Model:
|
||||
ContentPart
|
||||
*@
|
||||
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@{
|
||||
@{
|
||||
var comment = (Orchard.Comments.Models.CommentPart)Model.ContentPart;
|
||||
}
|
||||
|
||||
@Html.LinkOrDefault(comment.Record.Author, comment.Record.SiteName, new { rel = "nofollow" })
|
||||
@Html.LinkOrDefault(comment.Author, comment.SiteName, new { rel = "nofollow" })
|
@@ -1,12 +1,5 @@
|
||||
@*
|
||||
Model:
|
||||
ContentPart
|
||||
*@
|
||||
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Utility.Extensions;
|
||||
@{
|
||||
@{
|
||||
var comment = (Orchard.Comments.Models.CommentPart)Model.ContentPart;
|
||||
}
|
||||
|
||||
@T("said") <time datetime="@comment.Record.CommentDateUtc.GetValueOrDefault()">@Html.Link((string)Display.DateTimeRelative(dateTimeUtc: comment.Record.CommentDateUtc.GetValueOrDefault()).ToString(), "#comment-" + comment.Id)</time>
|
||||
@T("said") <time datetime="@comment.CommentDateUtc.GetValueOrDefault()">@Html.Link((string)Display.DateTimeRelative(dateTimeUtc: comment.CommentDateUtc.GetValueOrDefault()).ToString(), @Url.RouteUrl(comment.CommentedOnContentItemMetadata.DisplayRouteValues) + "#comment-" + comment.Id)</time>
|
@@ -0,0 +1,3 @@
|
||||
@if (Model.Content != null) {
|
||||
@Display(Model.Content)
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
@model Orchard.Comments.Models.CommentPart
|
||||
|
||||
@using Orchard.Comments.Models;
|
||||
|
||||
<fieldset class="who">
|
||||
<ol>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.Author, T("Name"))
|
||||
@Html.TextBoxFor(m => m.Author)
|
||||
</li>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.Email, T("Email"))
|
||||
@Html.TextBoxFor(m => m.Email)
|
||||
</li>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.SiteName, T("Url"))
|
||||
@Html.TextBoxFor(m => m.SiteName)
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
<fieldset class="what">
|
||||
<div>
|
||||
@Html.LabelFor(m => m.CommentText, T("Comment"))
|
||||
@Html.TextAreaFor(m => m.CommentText, new { rows = 10, cols = 30, @class = "comment-text" })
|
||||
@Html.HiddenFor(m => m.Id)
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
@Html.RadioButtonFor(m => m.Status, CommentStatus.Pending)
|
||||
<label class="forcheckbox" for="Status_Pending">@T("Pending")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(m => m.Status, CommentStatus.Approved)
|
||||
<label class="forcheckbox" for="Status_Approved">@T("Approved")</label>
|
||||
</div>
|
||||
<div>
|
||||
@Html.RadioButtonFor(m => m.Status, CommentStatus.Spam)
|
||||
<label class="forcheckbox" for="Status_Spam">@T("Mark as spam")</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<button class="primaryAction" type="submit">@T("Save")</button>
|
||||
</fieldset>
|
@@ -0,0 +1,40 @@
|
||||
@model Orchard.Comments.Models.CommentPart
|
||||
|
||||
|
||||
@if (WorkContext.CurrentUser == null) {
|
||||
<fieldset class="who">
|
||||
<legend id="add-comment">@T("Add a Comment")</legend>
|
||||
<ol>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.Author, T("Name"))
|
||||
@Html.TextBoxFor(m => m.Author)
|
||||
</li>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.Email, T("Email"))
|
||||
@Html.TextBoxFor(m => m.Email)
|
||||
</li>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.SiteName, T("Url"))
|
||||
@Html.TextBoxFor(m => m.SiteName)
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
}
|
||||
else {
|
||||
@Html.Hidden("Name", WorkContext.CurrentUser.UserName ?? "")
|
||||
@Html.Hidden("Email", WorkContext.CurrentUser.Email ?? "")
|
||||
}
|
||||
|
||||
@if (WorkContext.CurrentUser != null) { <h2 id="commenter">@if (WorkContext.CurrentUser != null) { @T("Hi, {0}!", Convert.ToString(Html.ItemDisplayText(WorkContext.CurrentUser)))}</h2> }
|
||||
<fieldset class="what">
|
||||
<ol>
|
||||
<li>
|
||||
@Html.LabelFor(m => m.CommentText, T("Comment"))
|
||||
@Html.TextAreaFor(m => m.CommentText, new { rows = 10, cols = 30, @class = "comment-text" })
|
||||
</li>
|
||||
<li>
|
||||
<button class="primaryAction" type="submit">@T("Submit Comment")</button>
|
||||
@Html.Hidden("CommentedOn", Model.CommentedOn)
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
@@ -1,5 +1,4 @@
|
||||
@model Orchard.Comments.Models.CommentsPart
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Localization;
|
||||
|
||||
<fieldset>
|
||||
|
@@ -1,5 +1,4 @@
|
||||
@model Orchard.Comments.Models.CommentSettingsPartRecord
|
||||
@using Orchard.Comments.Models;
|
||||
|
||||
<fieldset>
|
||||
<legend>@T("Comments")</legend>
|
||||
|
@@ -1,19 +0,0 @@
|
||||
@model IEnumerable<Orchard.Comments.Models.CommentPart>
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Utility.Extensions;
|
||||
<ul class="comments">
|
||||
@foreach (var comment in Model) {
|
||||
<li>
|
||||
<article class="comment" id="comment-@comment.Id">
|
||||
<header>
|
||||
<h4>
|
||||
<span class="who">@Display.CommentAuthor(ContentPart: comment)</span>
|
||||
<span class="when">@Display.CommentMetadata(ContentPart: comment)</span>
|
||||
</h4>
|
||||
</header>
|
||||
<p class="text">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText).Replace("\r\n", "<br />\r\n")))</p>
|
||||
</article>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
|
@@ -0,0 +1,46 @@
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@{
|
||||
var comment = (Orchard.Comments.Models.CommentPart)Model.ContentPart;
|
||||
}
|
||||
|
||||
<td>
|
||||
@if (comment.Status == CommentStatus.Spam) { @T("Spam") }
|
||||
else if (comment.Status == CommentStatus.Pending) { @T("Pending") }
|
||||
else { @T("Approved") }
|
||||
</td>
|
||||
<td>
|
||||
<div>@comment.Author</div>
|
||||
@if (HasText(comment.UserName) && comment.Author != comment.UserName) {
|
||||
<div class="authenticated-commenter-id">@comment.UserName</div>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@* would ideally have permalinks for individual comments *@
|
||||
<p><a href="@Url.RouteUrl(comment.CommentedOnContentItemMetadata.DisplayRouteValues)#comments"><time>@Display.DateTime(DateTimeUtc: comment.CommentDateUtc.GetValueOrDefault())</time></a></p>
|
||||
@if (comment.CommentText != null) {
|
||||
var ellipsized = Html.Ellipsize(comment.CommentText, 500);
|
||||
var paragraphed = new HtmlString(ellipsized.ToHtmlString().Replace("\r\n", "</p><p>"));
|
||||
<p>@paragraphed</p>
|
||||
}
|
||||
else {
|
||||
@T("[Empty]")
|
||||
}
|
||||
</td>
|
||||
<td>@Html.Link(comment.CommentedOnContentItemMetadata.DisplayText, @Url.RouteUrl(comment.CommentedOnContentItemMetadata.DisplayRouteValues))</td>
|
||||
<td>
|
||||
<div class="actions">
|
||||
@if (comment.Status != CommentStatus.Spam) {
|
||||
<a href="@Url.Action("MarkAsSpam", new { comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString() })" itemprop="RemoveUrl UnsafeUrl">@T("Spam")</a>@T(" | ")
|
||||
}
|
||||
@if (comment.Status != CommentStatus.Approved) {
|
||||
<a href="@Url.Action("Approve", new { comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString() })" itemprop="ApproveUrl UnsafeUrl">@T("Approve")</a>@T(" | ")
|
||||
}
|
||||
else {
|
||||
<a href="@Url.Action("Unapprove", new { comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString() })" itemprop="UnapproveUrl UnsafeUrl">@T("Unapprove")</a>@T(" | ")
|
||||
}
|
||||
<a href="@Url.Action("Edit", new { comment.Id })" title="@T("Edit")">@T("Edit")</a>@T(" | ")
|
||||
<a href="@Url.Action("Delete", new { comment.Id, returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString() })" itemprop="RemoveUrl UnsafeUrl">@T("Delete")</a>
|
||||
</div>
|
||||
</td>
|
@@ -0,0 +1,13 @@
|
||||
@{
|
||||
var comment = (Orchard.Comments.Models.CommentPart)Model.ContentPart;
|
||||
}
|
||||
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
<header>
|
||||
<h4>
|
||||
<span class="who">@Display.CommentAuthor(ContentPart: comment)</span>
|
||||
<span class="when">@Display.CommentMetadata(ContentPart: comment)</span>
|
||||
</h4>
|
||||
</header>
|
||||
<p class="text">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText).Replace("\r\n", "<br />\r\n")))</p>
|
@@ -0,0 +1,26 @@
|
||||
@using Orchard.Comments;
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@if (!Model.ContentPart.CommentsActive) {
|
||||
if (Model.ContentPart.Comments.Count > 0) {
|
||||
<div id="comments">
|
||||
<p class="comment-disabled">@T("Comments have been disabled for this content.")</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else if (WorkContext.CurrentUser == null && !AuthorizedFor(Permissions.AddComment)) {
|
||||
<h2 id="add-comment">@T("Add a Comment")</h2>
|
||||
<p class="info message">@T("You must {0} to comment.", Html.ActionLink(T("log on").ToString(), "LogOn",
|
||||
new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = string.Format("{0}#addacomment", Context.Request.RawUrl) }))</p>
|
||||
}
|
||||
else {
|
||||
@Html.ValidationSummary()
|
||||
using (Html.BeginFormAntiForgeryPost(Url.Action("Create", "Comment", new { Area = "Orchard.Comments", ReturnUrl = Context.Request.ToUrlString() }), FormMethod.Post, new { @class = "comment-form" })) {
|
||||
if (TempData.ContainsKey("Comments.InvalidCommentEditorShape")) {
|
||||
@Display(TempData["Comments.InvalidCommentEditorShape"]);
|
||||
}
|
||||
else {
|
||||
@Display(Model.EditorShape)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
<ul class="pageStatus">
|
||||
<li>
|
||||
@Display.CommentSummaryLinks(item: Model.ContentPart.ContentItem, count: Model.CommentCount, pendingCount: Model.PendingCount)
|
||||
@T(" | ")
|
||||
</li>
|
||||
<li>
|
||||
@Display.CommentSummaryLinks(item: Model.ContentPart.ContentItem, count: Model.CommentCount, pendingCount: Model.PendingCount)
|
||||
@T(" | ")
|
||||
</li>
|
||||
</ul>
|
@@ -1,2 +1 @@
|
||||
@using Orchard.Comments.ViewModels;
|
||||
<span class="commentcount">@T.Plural("1 Comment", "{0} Comments", (int)Model.CommentCount)</span>
|
||||
<span class="commentcount">@T.Plural("1 Comment", "{0} Comments", (int)Model.CommentCount)</span>
|
@@ -1,74 +0,0 @@
|
||||
@using Orchard.Comments.Models;
|
||||
@using Orchard.Comments;
|
||||
@using Orchard.Security;
|
||||
@using Orchard.Utility.Extensions;
|
||||
|
||||
@{
|
||||
var contextExists = TempData["CreateCommentContext.Name"] != null;
|
||||
var name = Convert.ToString(TempData["CreateCommentContext.Name"]);
|
||||
var commentText = Convert.ToString(TempData["CreateCommentContext.CommentText"]);
|
||||
var email = Convert.ToString(TempData["CreateCommentContext.Email"]);
|
||||
var siteName = Convert.ToString(TempData["CreateCommentContext.SiteName"]);
|
||||
}
|
||||
|
||||
@if (Model.ContentPart.Comments.Count > 0) {
|
||||
<div id="comments">
|
||||
<h2 class="comment-count">@T.Plural("1 Comment", "{0} Comments", (int)Model.ContentPart.Comments.Count)</h2>
|
||||
@{Html.RenderPartial("ListOfComments", (IEnumerable<Orchard.Comments.Models.CommentPart>)Model.ContentPart.Comments);}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (Model.ContentPart.CommentsActive == false) {
|
||||
if (Model.ContentPart.Comments.Count > 0) {
|
||||
<div id="comments">
|
||||
<p class="comment-disabled">@T("Comments have been disabled for this content.")</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else if (WorkContext.CurrentUser == null && !AuthorizedFor(Permissions.AddComment)) {
|
||||
<h2 id="add-comment">@T("Add a Comment")</h2>
|
||||
<p class="info message">@T("You must {0} to comment.", Html.ActionLink(T("log on").ToString(), "LogOn", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = string.Format("{0}#addacomment", Context.Request.RawUrl) }))</p>
|
||||
} else {
|
||||
using (Html.BeginForm("Create", "Comment", new { area = "Orchard.Comments" }, FormMethod.Post, new { @class = "comment-form" })) {
|
||||
@Html.ValidationSummary()
|
||||
if (WorkContext.CurrentUser == null) {
|
||||
|
||||
<fieldset class="who">
|
||||
<legend id="add-comment">@T("Add a Comment")</legend>
|
||||
<ol>
|
||||
<li>
|
||||
<label for="Name">@T("Name")</label>
|
||||
<input id="Name" class="text" name="Name" type="text" value="@(contextExists ? name : String.Empty)" />
|
||||
</li>
|
||||
<li>
|
||||
<label for="Email">@T("Email")</label>
|
||||
<input id="Email" class="text" name="Email" type="text" value="@(contextExists ? email : String.Empty)"/>
|
||||
</li>
|
||||
<li>
|
||||
<label for="SiteName">@T("Url")</label>
|
||||
<input id="SiteName" class="text" name="SiteName" type="text" value="@(contextExists ? siteName : String.Empty)"/>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
} else {
|
||||
@Html.Hidden("Name", WorkContext.CurrentUser.UserName ?? "")
|
||||
@Html.Hidden("Email", WorkContext.CurrentUser.Email ?? "")
|
||||
}
|
||||
|
||||
<h2 id="commenter">@if (WorkContext.CurrentUser != null) { @T("Hi, {0}!", Convert.ToString(Html.ItemDisplayText(WorkContext.CurrentUser)))}</h2>
|
||||
<fieldset class="what">
|
||||
<ol>
|
||||
<li>
|
||||
<label for="comment-text">@T("Comment")</label>
|
||||
<textarea id="comment-text" rows="10" cols="30" name="CommentText">@(contextExists ? commentText : String.Empty)</textarea>
|
||||
</li>
|
||||
<li>
|
||||
<button class="primaryAction" type="submit">@T("Submit Comment")</button>
|
||||
@Html.Hidden("CommentedOn", (int)Model.ContentPart.ContentItem.Id)
|
||||
@Html.Hidden("ReturnUrl", Context.Request.ToUrlString())
|
||||
@Html.AntiForgeryTokenOrchard()
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
@if (Model.ContentPart.Comments.Count > 0) {
|
||||
<div id="comments">
|
||||
<h2 class="comment-count">@T.Plural("1 Comment", "{0} Comments", (int)Model.ContentPart.Comments.Count)</h2>
|
||||
<ul class="comments">
|
||||
@foreach (var comment in Model.CommentShapes) {
|
||||
<li>
|
||||
<article class="comment" id="comment-@comment.ContentItem.Id">
|
||||
@Display(comment)
|
||||
</article>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
Reference in New Issue
Block a user