diff --git a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
index 8512c3825..c17b0c3dc 100644
--- a/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
+++ b/src/Orchard.Tests.Modules/Orchard.Tests.Modules.csproj
@@ -147,6 +147,7 @@
+
diff --git a/src/Orchard.Tests.Modules/XmlRpc/Controllers/HomeControllerTests.cs b/src/Orchard.Tests.Modules/XmlRpc/Controllers/HomeControllerTests.cs
index ff7e41af4..d9bb4b10c 100644
--- a/src/Orchard.Tests.Modules/XmlRpc/Controllers/HomeControllerTests.cs
+++ b/src/Orchard.Tests.Modules/XmlRpc/Controllers/HomeControllerTests.cs
@@ -37,6 +37,8 @@ namespace Orchard.Tests.Modules.XmlRpc.Controllers {
}
public class StubHandler : IXmlRpcHandler {
+ public void SetCapabilities(XElement element) {}
+
public void Process(XmlRpcContext context) {
ProcessCalls++;
context.Response = new XRpcMethodResponse();
diff --git a/src/Orchard.Tests.Modules/XmlRpc/Controllers/LiveWriterControllerTests.cs b/src/Orchard.Tests.Modules/XmlRpc/Controllers/LiveWriterControllerTests.cs
new file mode 100644
index 000000000..2df1e0831
--- /dev/null
+++ b/src/Orchard.Tests.Modules/XmlRpc/Controllers/LiveWriterControllerTests.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Web.Mvc;
+using System.Xml.Linq;
+using Autofac;
+using NUnit.Framework;
+using Orchard.Core.XmlRpc;
+using Orchard.Core.XmlRpc.Controllers;
+using Orchard.Core.XmlRpc.Models;
+using Orchard.Core.XmlRpc.Services;
+
+namespace Orchard.Tests.Modules.XmlRpc.Controllers {
+ [TestFixture]
+ public class LiveWriterControllerTests {
+ [Test]
+ public void HandlersShouldSetCapabilitiesForManifest() {
+ var thing = new StubHandler();
+ var thingToo = new StubTooHandler();
+
+ var builder = new ContainerBuilder();
+ builder.RegisterType();
+ builder.RegisterType().As>();
+ builder.RegisterType().As>();
+ builder.RegisterInstance(thing).As();
+ builder.RegisterInstance(thingToo).As();
+
+ var container = builder.Build();
+
+ var controller = container.Resolve();
+ var result = controller.Manifest() as ContentResult;
+ Assert.That(result, Is.Not.Null);
+ Assert.That(result.Content, Is.StringContaining("No"));
+ Assert.That(result.Content, Is.StringContaining("Yes"));
+ Assert.That(result.Content, Is.StringContaining("Maybe"));
+
+ }
+
+ public class StubHandler : IXmlRpcHandler {
+ public void SetCapabilities(XElement options) {
+ const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
+ options.SetElementValue(XName.Get("supportsGetTags", manifestUri), "No");
+ options.SetElementValue(XName.Get("keywordsAsTags", manifestUri), "Yes");
+ }
+
+ public void Process(XmlRpcContext context) { }
+
+ public int ProcessCalls { get; set; }
+ }
+
+ public class StubTooHandler : IXmlRpcHandler {
+ public void SetCapabilities(XElement options) {
+ const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
+ options.SetElementValue(XName.Get("supportsKeywords", manifestUri), "Maybe");
+ }
+
+ public void Process(XmlRpcContext context) { }
+
+ public int ProcessCalls { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj
index 663a745fd..5d9ba62af 100644
--- a/src/Orchard.Web/Core/Orchard.Core.csproj
+++ b/src/Orchard.Web/Core/Orchard.Core.csproj
@@ -245,6 +245,7 @@
+
diff --git a/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs b/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs
index c498ae11b..54501817a 100644
--- a/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs
+++ b/src/Orchard.Web/Core/XmlRpc/Controllers/LiveWriterController.cs
@@ -1,33 +1,52 @@
-using System.Web;
+using System;
+using System.Collections.Generic;
+using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using Orchard.Logging;
namespace Orchard.Core.XmlRpc.Controllers {
public class LiveWriterController : Controller {
+ private readonly IEnumerable _xmlRpcHandlers;
private const string ManifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
- public LiveWriterController() {
+ public LiveWriterController(IEnumerable xmlRpcHandlers) {
+ _xmlRpcHandlers = xmlRpcHandlers;
Logger = NullLogger.Instance;
}
protected ILogger Logger { get; set; }
-
+ [NoCache]
public ActionResult Manifest() {
Logger.Debug("Manifest requested");
var options = new XElement(
XName.Get("options", ManifestUri),
new XElement(XName.Get("clientType", ManifestUri), "Metaweblog"),
- new XElement(XName.Get("supportsSlug", ManifestUri), "Yes"));
+ new XElement(XName.Get("supportsKeywords", ManifestUri), "No"),
+ new XElement(XName.Get("supportsCategories", ManifestUri), "No"),
+ new XElement(XName.Get("supportsFileUpload", ManifestUri), "No"));
+
+ foreach (var handler in _xmlRpcHandlers)
+ handler.SetCapabilities(options);
var doc = new XDocument(new XElement(
XName.Get("manifest", ManifestUri),
options));
- Response.Cache.SetCacheability(HttpCacheability.NoCache);
return Content(doc.ToString(), "text/xml");
}
+
+ public class NoCache : ActionFilterAttribute {
+ public override void OnResultExecuting(ResultExecutingContext filterContext) {
+ filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
+ filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
+ filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
+ filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
+ filterContext.HttpContext.Response.Cache.SetNoStore();
+ base.OnResultExecuting(filterContext);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/XmlRpc/IXmlRpcDriver.cs b/src/Orchard.Web/Core/XmlRpc/IXmlRpcDriver.cs
new file mode 100644
index 000000000..949fa104b
--- /dev/null
+++ b/src/Orchard.Web/Core/XmlRpc/IXmlRpcDriver.cs
@@ -0,0 +1,5 @@
+namespace Orchard.Core.XmlRpc {
+ public interface IXmlRpcDriver {
+ void Process(int id);
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/XmlRpc/IXmlRpcHandler.cs b/src/Orchard.Web/Core/XmlRpc/IXmlRpcHandler.cs
index 9efee82fb..d87203632 100644
--- a/src/Orchard.Web/Core/XmlRpc/IXmlRpcHandler.cs
+++ b/src/Orchard.Web/Core/XmlRpc/IXmlRpcHandler.cs
@@ -1,5 +1,8 @@
-namespace Orchard.Core.XmlRpc {
+using System.Xml.Linq;
+
+namespace Orchard.Core.XmlRpc {
public interface IXmlRpcHandler : IDependency {
+ void SetCapabilities(XElement element);
void Process(XmlRpcContext context);
}
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Core/XmlRpc/XmlRpcContext.cs b/src/Orchard.Web/Core/XmlRpc/XmlRpcContext.cs
index a8d8d52ed..114a81f11 100644
--- a/src/Orchard.Web/Core/XmlRpc/XmlRpcContext.cs
+++ b/src/Orchard.Web/Core/XmlRpc/XmlRpcContext.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using Orchard.Core.XmlRpc.Models;
@@ -8,5 +9,6 @@ namespace Orchard.Core.XmlRpc {
public HttpContextBase HttpContext { get; set; }
public XRpcMethodCall Request { get; set; }
public XRpcMethodResponse Response { get; set; }
+ public ICollection _drivers = new List();
}
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
index 71f9e8843..eae373f93 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogController.cs
@@ -1,10 +1,6 @@
using System.Linq;
-using System.Web;
using System.Web.Mvc;
-using System.Web.Routing;
-using System.Xml.Linq;
using Orchard.Blogs.Extensions;
-using Orchard.Blogs.Models;
using Orchard.Blogs.Routing;
using Orchard.Blogs.Services;
using Orchard.Core.Feeds;
@@ -21,22 +17,19 @@ namespace Orchard.Blogs.Controllers {
private readonly IBlogPostService _blogPostService;
private readonly IBlogSlugConstraint _blogSlugConstraint;
private readonly IFeedManager _feedManager;
- private readonly RouteCollection _routeCollection;
public BlogController(
IOrchardServices services,
IBlogService blogService,
IBlogPostService blogPostService,
IBlogSlugConstraint blogSlugConstraint,
- IFeedManager feedManager,
- RouteCollection routeCollection,
+ IFeedManager feedManager,
IShapeFactory shapeFactory) {
_services = services;
_blogService = blogService;
_blogPostService = blogPostService;
_blogSlugConstraint = blogSlugConstraint;
_feedManager = feedManager;
- _routeCollection = routeCollection;
Logger = NullLogger.Instance;
Shape = shapeFactory;
}
@@ -79,64 +72,5 @@ namespace Orchard.Blogs.Controllers {
return View(blog);
}
-
- public ActionResult LiveWriterManifest(string blogSlug) {
- Logger.Debug("Live Writer Manifest requested");
-
- BlogPart blogPart = _blogService.Get(blogSlug);
-
- if (blogPart == null)
- return HttpNotFound();
-
- const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
-
- var options = new XElement(
- XName.Get("options", manifestUri),
- new XElement(XName.Get("clientType", manifestUri), "Metaweblog"),
- new XElement(XName.Get("supportsSlug", manifestUri), "Yes"),
- new XElement(XName.Get("supportsKeywords", manifestUri), "Yes"));
-
-
- var doc = new XDocument(new XElement(
- XName.Get("manifest", manifestUri),
- options));
-
- Response.Cache.SetCacheability(HttpCacheability.NoCache);
- return Content(doc.ToString(), "text/xml");
- }
-
- public ActionResult Rsd(string blogSlug) {
- Logger.Debug("RSD requested");
-
- BlogPart blogPart = _blogService.Get(blogSlug);
-
- if (blogPart == null)
- return HttpNotFound();
-
- const string manifestUri = "http://archipelago.phrasewise.com/rsd";
-
- var urlHelper = new UrlHelper(ControllerContext.RequestContext, _routeCollection);
- var url = urlHelper.Action("", "", new { Area = "XmlRpc" });
-
- var options = new XElement(
- XName.Get("service", manifestUri),
- new XElement(XName.Get("engineName", manifestUri), "Orchard CMS"),
- new XElement(XName.Get("engineLink", manifestUri), "http://orchardproject.net"),
- new XElement(XName.Get("homePageLink", manifestUri), "http://orchardproject.net"),
- new XElement(XName.Get("apis", manifestUri),
- new XElement(XName.Get("api", manifestUri),
- new XAttribute("name", "MetaWeblog"),
- new XAttribute("preferred", true),
- new XAttribute("apiLink", url),
- new XAttribute("blogID", blogPart.Id))));
-
- var doc = new XDocument(new XElement(
- XName.Get("rsd", manifestUri),
- new XAttribute("version", "1.0"),
- options));
-
- Response.Cache.SetCacheability(HttpCacheability.NoCache);
- return Content(doc.ToString(), "text/xml");
- }
}
}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/RemoteBlogPublishingController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/RemoteBlogPublishingController.cs
new file mode 100644
index 000000000..322440bb7
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/RemoteBlogPublishingController.cs
@@ -0,0 +1,59 @@
+using System.Collections.Generic;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Routing;
+using System.Xml.Linq;
+using Orchard.Blogs.Models;
+using Orchard.Blogs.Services;
+using Orchard.Environment.Extensions;
+using Orchard.Logging;
+
+namespace Orchard.Blogs.Controllers {
+ [OrchardFeature("Orchard.Blogs.RemotePublishing")]
+ public class RemoteBlogPublishingController : Controller {
+ private readonly IBlogService _blogService;
+ private readonly RouteCollection _routeCollection;
+
+ public RemoteBlogPublishingController(IOrchardServices services, IBlogService blogService, RouteCollection routeCollection) {
+ _blogService = blogService;
+ _routeCollection = routeCollection;
+ Logger = NullLogger.Instance;
+ }
+
+ protected ILogger Logger { get; set; }
+
+ public ActionResult Rsd(string blogSlug) {
+ Logger.Debug("RSD requested");
+
+ BlogPart blogPart = _blogService.Get(blogSlug);
+
+ if (blogPart == null)
+ return HttpNotFound();
+
+ const string manifestUri = "http://archipelago.phrasewise.com/rsd";
+
+ var urlHelper = new UrlHelper(ControllerContext.RequestContext, _routeCollection);
+ var url = urlHelper.Action("", "", new { Area = "XmlRpc" });
+
+ var options = new XElement(
+ XName.Get("service", manifestUri),
+ new XElement(XName.Get("engineName", manifestUri), "Orchard CMS"),
+ new XElement(XName.Get("engineLink", manifestUri), "http://orchardproject.net"),
+ new XElement(XName.Get("homePageLink", manifestUri), "http://orchardproject.net"),
+ new XElement(XName.Get("apis", manifestUri),
+ new XElement(XName.Get("api", manifestUri),
+ new XAttribute("name", "MetaWeblog"),
+ new XAttribute("preferred", true),
+ new XAttribute("apiLink", url),
+ new XAttribute("blogID", blogPart.Id))));
+
+ var doc = new XDocument(new XElement(
+ XName.Get("rsd", manifestUri),
+ new XAttribute("version", "1.0"),
+ options));
+
+ Response.Cache.SetCacheability(HttpCacheability.NoCache);
+ return Content(doc.ToString(), "text/xml");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Extensions/UrlHelperExtensions.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Extensions/UrlHelperExtensions.cs
index 19e81e140..96577cefa 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Extensions/UrlHelperExtensions.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Extensions/UrlHelperExtensions.cs
@@ -20,11 +20,11 @@ namespace Orchard.Blogs.Extensions {
}
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) {
- return urlHelper.AbsoluteAction(() => urlHelper.Action("LiveWriterManifest", "Blog", new { blogSlug = blogPart.As().Path, area = "Orchard.Blogs" }));
+ return urlHelper.AbsoluteAction(() => urlHelper.Action("Manifest", "LiveWriter", new { area = "XmlRpc" }));
}
public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) {
- return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "Blog", new { blogSlug = blogPart.As().Path, area = "Orchard.Blogs" }));
+ return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "RemoteBlogPublishing", new { blogSlug = blogPart.As().Path, area = "Orchard.Blogs" }));
}
public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) {
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj
index 6ba4015e9..2983c45c4 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj
@@ -67,6 +67,7 @@
+
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Routes.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Routes.cs
index 6f8b3b879..e6407fdcc 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Routes.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Routes.cs
@@ -202,30 +202,13 @@ namespace Orchard.Blogs {
},
new MvcRouteHandler())
},
- new RouteDescriptor {
- Priority = 11,
- Route = new Route(
- "{blogSlug}/wlwmanifest.xml",
- new RouteValueDictionary {
- {"area", "Orchard.Blogs"},
- {"controller", "Blog"},
- {"action", "LiveWriterManifest"}
- },
- new RouteValueDictionary {
- {"blogSlug", _blogSlugConstraint}
- },
- new RouteValueDictionary {
- {"area", "Orchard.Blogs"}
- },
- new MvcRouteHandler())
- },
new RouteDescriptor {
Priority = 11,
Route = new Route(
"{blogSlug}/rsd",
new RouteValueDictionary {
{"area", "Orchard.Blogs"},
- {"controller", "Blog"},
+ {"controller", "RemoteBlogPublishing"},
{"action", "Rsd"}
},
new RouteValueDictionary {
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs
index a079dc202..756af11dd 100644
--- a/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs
+++ b/src/Orchard.Web/Modules/Orchard.Blogs/Services/XmlRpcHandler.cs
@@ -1,7 +1,9 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
+using System.Xml.Linq;
using JetBrains.Annotations;
using Orchard.Blogs.Models;
using Orchard.ContentManagement;
@@ -44,6 +46,11 @@ namespace Orchard.Blogs.Services {
public ILogger Logger { get; set; }
+ public void SetCapabilities(XElement options) {
+ const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
+ options.SetElementValue(XName.Get("supportsSlug", manifestUri), "Yes");
+ }
+
public void Process(XmlRpcContext context) {
var urlHelper = new UrlHelper(context.ControllerContext.RequestContext, _routeCollection);
@@ -72,7 +79,8 @@ namespace Orchard.Blogs.Services {
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
(XRpcStruct)context.Request.Params[3].Value,
- Convert.ToBoolean(context.Request.Params[4].Value));
+ Convert.ToBoolean(context.Request.Params[4].Value),
+ context._drivers);
context.Response = new XRpcMethodResponse().Add(result);
}
@@ -92,7 +100,8 @@ namespace Orchard.Blogs.Services {
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
(XRpcStruct)context.Request.Params[3].Value,
- Convert.ToBoolean(context.Request.Params[4].Value));
+ Convert.ToBoolean(context.Request.Params[4].Value),
+ context._drivers);
context.Response = new XRpcMethodResponse().Add(result);
}
@@ -102,7 +111,8 @@ namespace Orchard.Blogs.Services {
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
Convert.ToString(context.Request.Params[3].Value),
- Convert.ToBoolean(context.Request.Params[4].Value));
+ Convert.ToBoolean(context.Request.Params[4].Value),
+ context._drivers);
context.Response = new XRpcMethodResponse().Add(result);
}
}
@@ -152,7 +162,8 @@ namespace Orchard.Blogs.Services {
string userName,
string password,
XRpcStruct content,
- bool publish) {
+ bool publish,
+ IEnumerable drivers) {
var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(Permissions.EditBlogPost, user, null);
@@ -191,6 +202,9 @@ namespace Orchard.Blogs.Services {
if (publish)
_blogPostService.Publish(blogPost);
+ foreach (var driver in drivers)
+ driver.Process(blogPost.Id);
+
return blogPost.Id;
}
@@ -210,12 +224,7 @@ namespace Orchard.Blogs.Services {
return CreateBlogStruct(blogPost, urlHelper);
}
- private bool MetaWeblogEditPost(
- int postId,
- string userName,
- string password,
- XRpcStruct content,
- bool publish) {
+ private bool MetaWeblogEditPost(int postId, string userName, string password, XRpcStruct content, bool publish, ICollection drivers) {
var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null);
@@ -233,19 +242,16 @@ namespace Orchard.Blogs.Services {
blogPost.Slug = slug;
blogPost.Text = description;
- if (publish) {
+ if (publish)
_blogPostService.Publish(blogPost);
- }
+
+ foreach (var driver in drivers)
+ driver.Process(blogPost.Id);
return true;
}
- private bool MetaWeblogDeletePost(
- string appkey,
- string postId,
- string userName,
- string password,
- bool publish) {
+ private bool MetaWeblogDeletePost(string appkey, string postId, string userName, string password, bool publish, ICollection drivers) {
var user = _membershipService.ValidateUser(userName, password);
_authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null);
@@ -253,6 +259,9 @@ namespace Orchard.Blogs.Services {
if (blogPost == null)
throw new ArgumentException();
+ foreach (var driver in drivers)
+ driver.Process(blogPost.Id);
+
_blogPostService.Delete(blogPost);
return true;
}
diff --git a/src/Orchard.Web/Modules/Orchard.Media/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Media/Services/XmlRpcHandler.cs
index d6c72a73a..cdeb7974f 100644
--- a/src/Orchard.Web/Modules/Orchard.Media/Services/XmlRpcHandler.cs
+++ b/src/Orchard.Web/Modules/Orchard.Media/Services/XmlRpcHandler.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Web;
+using System.Xml.Linq;
using JetBrains.Annotations;
using Orchard.Core.XmlRpc;
using Orchard.Core.XmlRpc.Models;
@@ -18,6 +19,11 @@ namespace Orchard.Media.Services {
_authorizationService = authorizationService;
}
+ public void SetCapabilities(XElement options) {
+ const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
+ options.SetElementValue(XName.Get("supportsFileUpload", manifestUri), "Yes");
+ }
+
public void Process(XmlRpcContext context) {
var uriBuilder = new UriBuilder(context.HttpContext.Request.ToUrlString()) {
Path = context.HttpContext.Request.ApplicationPath,
diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj
index a58353f55..dc5e821d7 100644
--- a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj
+++ b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj
@@ -72,6 +72,7 @@
+
diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs
new file mode 100644
index 000000000..b44d6b3f8
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.Tags/Services/XmlRpcHandler.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml.Linq;
+using Orchard.ContentManagement;
+using Orchard.Core.XmlRpc;
+using Orchard.Core.XmlRpc.Models;
+using Orchard.Security;
+using Orchard.Tags.Helpers;
+
+namespace Orchard.Tags.Services {
+ public class XmlRpcHandler : IXmlRpcHandler {
+ private readonly IMembershipService _membershipService;
+ private readonly IAuthorizationService _authorizationService;
+ private readonly IContentManager _contentManager;
+ private readonly ITagService _tagService;
+ private readonly IOrchardServices _orchardServices;
+ private IEnumerable _tags;
+
+ public XmlRpcHandler(
+ IMembershipService membershipService,
+ IAuthorizationService authorizationService,
+ IContentManager contentManager,
+ ITagService tagService,
+ IOrchardServices orchardServices) {
+ _membershipService = membershipService;
+ _authorizationService = authorizationService;
+ _contentManager = contentManager;
+ _tagService = tagService;
+ _orchardServices = orchardServices;
+ }
+
+ public void SetCapabilities(XElement options) {
+ const string manifestUri = "http://schemas.microsoft.com/wlw/manifest/weblog";
+ options.SetElementValue(XName.Get("supportsKeywords", manifestUri), "Yes");
+ options.SetElementValue(XName.Get("supportsGetTags", manifestUri), "Yes");
+ options.SetElementValue(XName.Get("keywordsAsTags", manifestUri), "Yes");
+ }
+
+ public void Process(XmlRpcContext context) {
+ switch (context.Request.MethodName) {
+ case "wp.getTags":
+ var tags = MetaWeblogGetTags(
+ Convert.ToString(context.Request.Params[0].Value),
+ Convert.ToString(context.Request.Params[1].Value),
+ Convert.ToString(context.Request.Params[2].Value));
+ context.Response = new XRpcMethodResponse().Add(tags);
+ break;
+ case "metaWeblog.newPost":
+ MetaWeblogUpdateTags(
+ GetId(context.Response),
+ Convert.ToString(context.Request.Params[0].Value),
+ Convert.ToString(context.Request.Params[1].Value),
+ Convert.ToString(context.Request.Params[2].Value),
+ (XRpcStruct)context.Request.Params[3].Value,
+ Convert.ToBoolean(context.Request.Params[4].Value),
+ context._drivers);
+ break;
+ case "metaWeblog.editPost":
+ MetaWeblogUpdateTags(
+ GetId(context.Response),
+ Convert.ToString(context.Request.Params[0].Value),
+ Convert.ToString(context.Request.Params[1].Value),
+ Convert.ToString(context.Request.Params[2].Value),
+ (XRpcStruct)context.Request.Params[3].Value,
+ Convert.ToBoolean(context.Request.Params[4].Value),
+ context._drivers);
+ break;
+ }
+ }
+
+ private static int GetId(XRpcMethodResponse response) {
+ return response != null && response.Params.Count == 1 && response.Params[0].Value is int
+ ? Convert.ToInt32(response.Params[0].Value)
+ : 0;
+ }
+
+ private XRpcArray MetaWeblogGetTags(string appKey, string userName, string password) {
+ var user = _membershipService.ValidateUser(userName, password);
+ _authorizationService.CheckAccess(StandardPermissions.AccessFrontEnd, user, null);
+
+ var array = new XRpcArray();
+ foreach (var tag in _tagService.GetTags()) {
+ var thisTag = tag;
+ array.Add(new XRpcStruct()
+ .Set("tag_id", thisTag.TagName)
+ .Set("name", thisTag.TagName));
+ // nyi - not yet implemented
+ //.Set("count", "")
+ //.Set("slug", "")
+ //.Set("html_url", "")
+ //.Set("rss_url", ""));
+ }
+
+ return array;
+ }
+
+ private void MetaWeblogUpdateTags(int contentItemId, string appKey, string userName, string password, XRpcStruct content, bool publish, ICollection drivers) {
+ var user = _membershipService.ValidateUser(userName, password);
+ _authorizationService.CheckAccess(Permissions.ApplyTag, user, null);
+
+ var rawTags = content.Optional("mt_keywords");
+ if (string.IsNullOrWhiteSpace(rawTags))
+ return;
+
+ var driver = new XmlRpcDriver(id => {
+ var contentItem = _contentManager.Get(id);
+ if (contentItem == null)
+ return;
+
+ _orchardServices.WorkContext.CurrentUser = user;
+ _tagService.UpdateTagsForContentItem(id, _tags);
+ });
+
+ _tags = TagHelpers.ParseCommaSeparatedTagNames(rawTags);
+ if (contentItemId > 0)
+ driver.Process(contentItemId);
+ else
+ drivers.Add(driver);
+ }
+
+ public class XmlRpcDriver : IXmlRpcDriver {
+ private readonly Action _process;
+
+ public XmlRpcDriver(Action process) {
+ _process = process;
+ }
+
+ public void Process(int id) {
+ _process(id);
+ }
+ }
+ }
+}
\ No newline at end of file