--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-12-02 17:18:38 -08:00
144 changed files with 1085 additions and 289 deletions

View File

@@ -15,18 +15,18 @@ Scenario: I can create a new blog and blog post
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "my-blog"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
When I go to "admin/blogs"
And I go to "admin/blogs"
And I follow "My Blog"
Then I should see "foo"
When I follow "New Post"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
| Body.Text | Hi there. |
And I hit "Publish Now"
And I go to "my-blog/my-post"
And I go to "my-blog"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
And I should see "<h1[^>]*>.*?My Post.*?</h1>"
When I go to "my-blog/my-post"
Then I should see "<h1[^>]*>.*?My Post.*?</h1>"
And I should see "Hi there."

View File

@@ -93,17 +93,11 @@ this.ScenarioSetup(scenarioInfo);
#line 17
testRunner.And("I hit \"Save\"");
#line 18
testRunner.And("I go to \"my-blog\"");
testRunner.And("I go to \"admin/blogs\"");
#line 19
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 20
testRunner.When("I go to \"admin/blogs\"");
#line 21
testRunner.And("I follow \"My Blog\"");
#line 22
testRunner.Then("I should see \"foo\"");
#line 23
testRunner.When("I follow \"New Post\"");
#line 20
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -114,12 +108,18 @@ this.ScenarioSetup(scenarioInfo);
table2.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 24
#line 21
testRunner.And("I fill in", ((string)(null)), table2);
#line 28
#line 25
testRunner.And("I hit \"Publish Now\"");
#line 26
testRunner.And("I go to \"my-blog\"");
#line 27
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"");
#line 28
testRunner.And("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 29
testRunner.And("I go to \"my-blog/my-post\"");
testRunner.When("I go to \"my-blog/my-post\"");
#line 30
testRunner.Then("I should see \"<h1[^>]*>.*?My Post.*?</h1>\"");
#line 31

View File

@@ -0,0 +1,44 @@
Feature: Comments
In order to enable simple comment capabilities on my site
As an author
I want to allow comments to be safely posted on specific content item pages
Scenario: HTML markup in any given comment is encoded
Given I have installed Orchard
When I go to "admin/blogs/create"
And I fill in
| name | value |
| Routable.Title | My Blog |
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I fill in
| name | value |
| Routable.Title | My Post |
| Body.Text | Hi there. |
And I hit "Publish Now"
And I go to "my-blog/my-post"
And I fill in
| name | value |
| CommentText | This is<br id="bad-br" />a <a href="#">link</a>. |
And I hit "Submit Comment"
And I am redirected
# because the ToUrlString extension method breaks in this specific (test) environment, the returnUrl is broken...
And I go to "my-blog/my-post"
Then I should see "This is&lt;br id=&quot;bad-br&quot; /&gt;a &lt;a href"
And I should not see "<br id="bad-br" />"
# another workaround because of ToUrlString in this environment
When I go to "Users/Account/LogOff"
And I am redirected
And I go to "my-blog/my-post"
And I fill in
| name | value |
| Name | Some One |
| CommentText | This is<br id="bad-anon-br" />a <a href="#">link</a>. |
And I hit "Submit Comment"
And I am redirected
# because the ToUrlString extension method breaks in this specific (test) environment, the returnUrl is broken...
And I go to "my-blog/my-post"
Then I should see "This is&lt;br id=&quot;bad-anon-br&quot; /&gt;a &lt;a href"
And I should not see "<br id="bad-anon-br" />"

152
src/Orchard.Specs/Comments.feature.cs generated Normal file
View File

@@ -0,0 +1,152 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.4.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#region Designer generated code
namespace Orchard.Specs
{
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Comments")]
public partial class CommentsFeature
{
private static TechTalk.SpecFlow.ITestRunner testRunner;
#line 1 "Comments.feature"
#line hidden
[NUnit.Framework.TestFixtureSetUpAttribute()]
public virtual void FeatureSetup()
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Comments", "In order to enable simple comment capabilities on my site\r\nAs an author\r\nI want t" +
"o allow comments to be safely posted on specific content item pages", GenerationTargetLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
[NUnit.Framework.TestFixtureTearDownAttribute()]
public virtual void FeatureTearDown()
{
testRunner.OnFeatureEnd();
testRunner = null;
}
public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
{
testRunner.OnScenarioStart(scenarioInfo);
}
[NUnit.Framework.TearDownAttribute()]
public virtual void ScenarioTearDown()
{
testRunner.OnScenarioEnd();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("HTML markup in any given comment is encoded")]
public virtual void HTMLMarkupInAnyGivenCommentIsEncoded()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("HTML markup in any given comment is encoded", ((string[])(null)));
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"admin/blogs/create\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"Routable.Title",
"My Blog"});
#line 9
testRunner.And("I fill in", ((string)(null)), table1);
#line 12
testRunner.And("I hit \"Save\"");
#line 13
testRunner.And("I go to \"admin/blogs\"");
#line 14
testRunner.And("I follow \"My Blog\"");
#line 15
testRunner.And("I follow \"New Post\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table2.AddRow(new string[] {
"Routable.Title",
"My Post"});
table2.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 16
testRunner.And("I fill in", ((string)(null)), table2);
#line 20
testRunner.And("I hit \"Publish Now\"");
#line 21
testRunner.And("I go to \"my-blog/my-post\"");
#line hidden
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table3.AddRow(new string[] {
"CommentText",
"This is<br id=\"bad-br\" />a <a href=\"#\">link</a>."});
#line 22
testRunner.And("I fill in", ((string)(null)), table3);
#line 25
testRunner.And("I hit \"Submit Comment\"");
#line 26
testRunner.And("I am redirected");
#line 28
testRunner.And("I go to \"my-blog/my-post\"");
#line 29
testRunner.Then("I should see \"This is&lt;br id=&quot;bad-br&quot; /&gt;a &lt;a href\"");
#line 30
testRunner.And("I should not see \"<br id=\"bad-br\" />\"");
#line 32
testRunner.When("I go to \"Users/Account/LogOff\"");
#line 33
testRunner.And("I am redirected");
#line 34
testRunner.And("I go to \"my-blog/my-post\"");
#line hidden
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table4.AddRow(new string[] {
"Name",
"Some One"});
table4.AddRow(new string[] {
"CommentText",
"This is<br id=\"bad-anon-br\" />a <a href=\"#\">link</a>."});
#line 35
testRunner.And("I fill in", ((string)(null)), table4);
#line 39
testRunner.And("I hit \"Submit Comment\"");
#line 40
testRunner.And("I am redirected");
#line 42
testRunner.And("I go to \"my-blog/my-post\"");
#line 43
testRunner.Then("I should see \"This is&lt;br id=&quot;bad-anon-br&quot; /&gt;a &lt;a href\"");
#line 44
testRunner.And("I should not see \"<br id=\"bad-anon-br\" />\"");
#line hidden
testRunner.CollectScenarioErrors();
}
}
}
#endregion

View File

@@ -1,6 +1,9 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation targetFramework="4.0">
<assemblies>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -15,7 +15,9 @@
</sectionGroup>
</configSections>
<appSettings/>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.diagnostics configSource="Config\Diagnostics.config"/>
<system.web.webPages.razor>

View File

@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using Orchard.Specs.Util;
@@ -45,7 +46,28 @@ namespace Orchard.Specs.Hosting {
string setCookie;
if (details.ResponseHeaders.TryGetValue("Set-Cookie", out setCookie)) {
Trace.WriteLine(string.Format("Set-Cookie: {0}", setCookie));
webHost.Cookies = (webHost.Cookies + ';' + setCookie.Split(';').FirstOrDefault()).Trim(';');
var cookieName = setCookie.Split(';')[0].Split('=')[0];
DateTime expires;
if (!string.IsNullOrEmpty(webHost.Cookies)
&& setCookie.Contains("expires=")
&& DateTime.TryParse(setCookie.Split(new[] { "expires=" }, 2, StringSplitOptions.None)[1].Split(';')[0], out expires)
&& expires < DateTime.Now) {
// remove
Trace.WriteLine(string.Format("Removing cookie: {0}", cookieName));
webHost.Cookies = Regex.Replace(webHost.Cookies, string.Format("{0}=[^;]*;?", cookieName), "");
}
else if (!string.IsNullOrEmpty(webHost.Cookies)
&& Regex.IsMatch(webHost.Cookies, string.Format("\b{0}=", cookieName))) {
// replace
Trace.WriteLine(string.Format("Replacing cookie: {0}", cookieName));
webHost.Cookies = Regex.Replace(webHost.Cookies, string.Format("{0}=[^;]*(;?)", cookieName), string.Format("{0}$1", setCookie.Split(';')[0]));
}
else {
// add
Trace.WriteLine(string.Format("Adding cookie: {0}", cookieName));
webHost.Cookies = (webHost.Cookies + ';' + setCookie.Split(';').FirstOrDefault()).Trim(';');
}
Trace.WriteLine(string.Format("Cookie jar: {0}", webHost.Cookies));
}
return details;

View File

@@ -23,7 +23,9 @@
</sectionGroup>
</configSections>
<appSettings/>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<!--

View File

@@ -137,6 +137,11 @@
<DesignTime>True</DesignTime>
<DependentUpon>Blogs.feature</DependentUpon>
</Compile>
<Compile Include="Comments.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Comments.feature</DependentUpon>
</Compile>
<Compile Include="ContentRights.feature.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@@ -234,6 +239,10 @@
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Blogs.feature.cs</LastGenOutput>
</None>
<None Include="Comments.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Comments.feature.cs</LastGenOutput>
</None>
<None Include="ContentRights.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>ContentRights.feature.cs</LastGenOutput>

View File

@@ -191,6 +191,7 @@ namespace Orchard.Tests.Modules.Users.Controllers {
registrationSettings.UsersCanRegister = true;
registrationSettings.UsersAreModerated = true;
registrationSettings.NotifyModeration = true;
registrationSettings.NotificationsRecipients = "admin";
_container.Resolve<IWorkContextAccessor>().GetContext().CurrentSite.As<SiteSettingsPart>().SuperUser = "admin";
_session.Flush();

View File

@@ -14,7 +14,21 @@ namespace Orchard.Tests {
Resolve(_container);
}
#if false
// technically more accurate, and doesn't work
[SetUp]
public virtual void Init() {
var hostBuilder = new ContainerBuilder();
var hostContainer = hostBuilder.Build();
var shellContainer = hostContainer.BeginLifetimeScope("shell", shellBuilder => Register(shellBuilder));
var workContainer = shellContainer.BeginLifetimeScope("work");
_container = workContainer;
Resolve(_container);
}
#endif
protected virtual void Register(ContainerBuilder builder) { }
protected virtual void Resolve(IContainer container) { }
protected virtual void Resolve(ILifetimeScope container) { }
}
}

View File

@@ -21,7 +21,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_parser = container.Resolve<IPlacementFileParser>();
_folder = container.Resolve<InMemoryWebSiteFolder>();
}

View File

@@ -39,7 +39,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
builder.RegisterModule(new ShapeAttributeBindingModule());
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
// implementation resorts to orchard host to resolve "current scope" services
container.Resolve<Mock<IOrchardHostContainer>>()
.Setup(x => x.Resolve<IComponentContext>())

View File

@@ -97,7 +97,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
}
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_features = new List<FeatureDescriptor>();
container.Resolve<Mock<IExtensionManager>>()

View File

@@ -22,11 +22,12 @@ namespace Orchard.Tests.Environment {
}
protected override void Register(ContainerBuilder builder) {
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking();
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
container.Mock<IHttpContextAccessor>()
.Setup(x => x.Current())
.Returns(() => _httpContextCurrent);

View File

@@ -21,6 +21,7 @@ namespace Orchard.Tests.Environment.ShellBuilders {
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<ShellContextFactory>().As<IShellContextFactory>();
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking(Moq.MockBehavior.Strict);
_container = builder.Build();

View File

@@ -23,6 +23,7 @@ namespace Orchard.Tests.Environment.State {
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<DefaultProcessingEngine>().As<IProcessingEngine>();
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterAutoMocking();
_container = builder.Build();

View File

@@ -36,6 +36,7 @@ namespace Orchard.Tests.Mvc.Routes {
rootBuilder.Register(ctx => _routes);
rootBuilder.RegisterType<ShellRoute>().InstancePerDependency();
rootBuilder.RegisterType<RunningShellTable>().As<IRunningShellTable>().SingleInstance();
rootBuilder.RegisterModule(new WorkContextModule());
rootBuilder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>().InstancePerMatchingLifetimeScope("shell");
rootBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>();

View File

@@ -12,6 +12,7 @@ namespace Orchard.Tests.Tasks {
public class SweepGeneratorTests : ContainerTestBase {
protected override void Register(ContainerBuilder builder) {
builder.RegisterAutoMocking(MockBehavior.Loose);
builder.RegisterModule(new WorkContextModule());
builder.RegisterType<WorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterType<SweepGenerator>();
}

View File

@@ -29,7 +29,7 @@ namespace Orchard.Tests.UI {
throw new NotImplementedException("this test fixture needs to move to modules tests now");
}
protected override void Resolve(IContainer container) {
protected override void Resolve(ILifetimeScope container) {
_workContext = container.Resolve<IWorkContextAccessor>().CreateWorkContextScope().WorkContext;
}

View File

@@ -9,7 +9,7 @@ using Moq;
namespace Orchard.Tests.Utility {
public static class ContainerExtensions {
public static Mock<T> Mock<T>(this IContainer container) where T : class {
public static Mock<T> Mock<T>(this IComponentContext container) where T : class {
return container.Resolve<Mock<T>>();
}

View File

@@ -5,6 +5,58 @@ using Orchard.Utility.Extensions;
namespace Orchard.Tests.Utility.Extensions {
[TestFixture]
public class StringExtensionsTests {
[Test]
public void CamelFriendly_CamelCasedStringMadeFriendly() {
const string aCamel = "aCamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("a Camel"));
}
[Test]
public void CamelFriendly_PascalCasedStringMadeFriendly() {
const string aCamel = "ACamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("A Camel"));
}
[Test]
public void CamelFriendly_LowerCasedStringMadeFriendly() {
const string aCamel = "acamel";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching("acamel"));
}
[Test]
public void CamelFriendly_EmptyStringReturnsEmptyString() {
const string aCamel = "";
Assert.That(aCamel.CamelFriendly(), Is.StringMatching(""));
}
[Test]
public void CamelFriendly_NullValueReturnsEmptyString() {
const string aCamel = null;
Assert.That(aCamel.CamelFriendly(), Is.StringMatching(""));
}
[Test]
public void Ellipsize_LongStringTruncatedToNearestWord() {
const string toEllipsize = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur&#160;&#8230;"));
}
[Test]
public void Ellipsize_ShortStringReturnedAsSame() {
const string toEllipsize = "Lorem ipsum";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching("Lorem ipsum"));
}
[Test]
public void Ellipsize_EmptyStringReturnsEmptyString() {
const string toEllipsize = "";
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching(""));
}
[Test]
public void Ellipsize_NullValueReturnsEmptyString() {
const string toEllipsize = null;
Assert.That(toEllipsize.Ellipsize(45), Is.StringMatching(""));
}
[Test]
public void Ellipsize_CustomEllipsisStringIsUsed() {
const string toEllipsize = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(toEllipsize.Ellipsize(45, "........"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur........"));
}
[Test]
public void HtmlClassify_ValidReallySimpleClassNameReturnsSame() {
const string toClassify = "someclass";
@@ -40,6 +92,17 @@ namespace Orchard.Tests.Utility.Extensions {
const string toClassify = "PascalCased";
Assert.That(toClassify.HtmlClassify(), Is.StringMatching("pascal-cased"));
}
[Test]
public void HtmlClassify_EmptyStringReturnsEmptyString() {
const string toClassify = "";
Assert.That(toClassify.HtmlClassify(), Is.StringMatching(""));
}
[Test]
public void HtmlClassify_NullValueReturnsEmptyString() {
const string toClassify = null;
Assert.That(toClassify.HtmlClassify(), Is.StringMatching(""));
}
[Test]
public void OrDefault_ReturnsDefaultForNull() {
const string s = null;
@@ -47,15 +110,61 @@ namespace Orchard.Tests.Utility.Extensions {
Assert.That(s.OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsDefault() {
public void OrDefault_ReturnsDefaultIfEmpty() {
var def = new LocalizedString("test");
Assert.That("".OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsDefaultIfNull() {
var def = new LocalizedString("test");
Assert.That(((string)null).OrDefault(def).Text, Is.SameAs("test"));
}
[Test]
public void OrDefault_ReturnsString() {
var def = new LocalizedString("test");
Assert.That("bar".OrDefault(def).Text, Is.SameAs("bar"));
}
[Test]
public void RemoveTags_StringWithNoTagsReturnsSame() {
const string fullOfTags = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam.";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void RemoveTags_SimpleWellFormedTagsAreRemoved() {
const string fullOfTags = @"<p><em>Lorem ipsum</em> dolor sit amet, consectetur <a href=""#"">adipiscing</a> elit. Maecenas sed purus quis purus orci aliquam.</p>";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void RemoveTags_EmptyStringReturnsEmptyString() {
const string fullOfTags = "";
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching(""));
}
[Test]
public void RemoveTags_NullValueReturnsEmptyString() {
const string fullOfTags = null;
Assert.That(fullOfTags.RemoveTags(), Is.StringMatching(""));
}
[Test]
public void ReplaceNewLinesWith_ReplaceCRLFWithHtmlBR() {
const string lotsOfLineFeeds = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\nMaecenas sed purus quis purus orci aliquam.";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br />Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void ReplaceNewLinesWith_ReplaceCRLFWithHtmlPsAndCRLF() {
const string lotsOfLineFeeds = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\nMaecenas sed purus quis purus orci aliquam.";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith(@"</p>$1<p>"), Is.StringMatching("Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>\r\n<p>Maecenas sed purus quis purus orci aliquam."));
}
[Test]
public void ReplaceNewLinesWith_EmptyStringReturnsEmptyString() {
const string lotsOfLineFeeds = "";
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching(""));
}
[Test]
public void ReplaceNewLinesWith_NullValueReturnsEmptyString() {
const string lotsOfLineFeeds = null;
Assert.That(lotsOfLineFeeds.ReplaceNewLinesWith("<br />"), Is.StringMatching(""));
}
}
}

View File

@@ -1,7 +0,0 @@
using Orchard.Core.Common.Fields;
namespace Orchard.Core.Common.ViewModels {
public class TextContentFieldDisplayViewModel {
public TextField Text { get; set; }
}
}

View File

@@ -1,14 +0,0 @@
using System.ComponentModel.DataAnnotations;
using Orchard.Core.Common.Fields;
namespace Orchard.Core.Common.ViewModels {
public class TextContentFieldEditorViewModel {
public TextField TextField { get; set; }
[Required]
public string Text {
get { return TextField.Value; }
set { TextField.Value = value; }
}
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,30 +0,0 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Containers.Models;
using Orchard.Data;
namespace Orchard.Core.Containers.Drivers {
public class ContainerCustomPartDriver : ContentPartDriver<ContainerCustomPart> {
protected override DriverResult Editor(ContainerCustomPart part, dynamic shapeHelper) {
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(ContainerCustomPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_ContainerCustom_Edit",
() => {
if (updater != null)
updater.TryUpdateModel(part, "ContainerCustom", null, null);
return shapeHelper.EditorTemplate(TemplateName: "ContainerCustom", Model: part, Prefix: "ContainerCustom");
});
}
}
public class ContainerCustomPartHandler : ContentHandler {
public ContainerCustomPartHandler(IRepository<ContainerCustomPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
}
}

View File

@@ -35,16 +35,16 @@ namespace Orchard.Core.Containers.Drivers {
}
protected override DriverResult Editor(ContainerPart part, dynamic shapeHelper) {
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(ContainerPart part, IUpdateModel updater, dynamic shapeHelper) {
// if there are no containable items then show a nice little warning
if (!_contentDefinitionManager.ListTypeDefinitions()
.Where(typeDefinition => typeDefinition.Parts.Any(partDefinition => partDefinition.PartDefinition.Name == "ContainablePart")).Any()) {
Services.Notifier.Warning(T("There are no content types in the system with a Containable part attached. Consider adding a Containable part to some content type, existing or new, in order to relate items to this (Container enabled) item."));
}
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(ContainerPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_Container_Edit",
() => {

View File

@@ -86,7 +86,7 @@ namespace Orchard.Core.Containers.Drivers {
part.Record.PageSize = 5;
part.Record.OrderByProperty = part.Is<CommonPart>() ? "CommonPart.PublishedUtc" : "";
part.Record.OrderByDirection = (int)OrderByDirection.Descending;
part.Record.FilterByProperty = "ContainerCustomPart.CustomOne";
part.Record.FilterByProperty = "CustomPropertiesPart.CustomOne";
part.Record.FilterByOperator = "=";
});
}

View File

@@ -0,0 +1,30 @@
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Containers.Models;
using Orchard.Data;
namespace Orchard.Core.Containers.Drivers {
public class CustomPropertiesPartDriver : ContentPartDriver<CustomPropertiesPart> {
protected override DriverResult Editor(CustomPropertiesPart part, dynamic shapeHelper) {
return Editor(part, null, shapeHelper);
}
protected override DriverResult Editor(CustomPropertiesPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape(
"Parts_CustomProperties_Edit",
() => {
if (updater != null)
updater.TryUpdateModel(part, "CustomProperties", null, null);
return shapeHelper.EditorTemplate(TemplateName: "CustomProperties", Model: part, Prefix: "CustomProperties");
});
}
}
public class CustomPropertiesPartHandler : ContentHandler {
public CustomPropertiesPartHandler(IRepository<CustomPropertiesPartRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
}
}

View File

@@ -21,20 +21,20 @@ namespace Orchard.Core.Containers.Extensions
? query.OrderByDescending<RoutePartRecord, string>(record => record.Slug)
: query.OrderBy<RoutePartRecord, string>(record => record.Slug);
break;
case "ContainerCustomPart.CustomOne":
case "CustomPropertiesPart.CustomOne":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomOne)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomOne);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomOne)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomOne);
break;
case "ContainerCustomPart.CustomTwo":
case "CustomPropertiesPart.CustomTwo":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomTwo)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomTwo);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomTwo)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomTwo);
break;
case "ContainerCustomPart.CustomThree":
case "CustomPropertiesPart.CustomThree":
query = descendingOrder
? query.OrderByDescending<ContainerCustomPartRecord, string>(record => record.CustomThree)
: query.OrderBy<ContainerCustomPartRecord, string>(record => record.CustomThree);
? query.OrderByDescending<CustomPropertiesPartRecord, string>(record => record.CustomThree)
: query.OrderBy<CustomPropertiesPartRecord, string>(record => record.CustomThree);
break;
default: // "CommonPart.PublishedUtc"
query = descendingOrder
@@ -69,18 +69,18 @@ namespace Orchard.Core.Containers.Extensions
{"CommonPart.PublishedUtc|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CommonPartRecord>(r => r.PublishedUtc == DateTime.Parse(s)))}, // todo: (heskew) not practical as is. needs some sense of precision....
{"CommonPart.PublishedUtc|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CommonPartRecord>(r => true /* can't modified PublishedUtc for partial comparisons */))},
// todo: (hesekw) this could benefit from a better filter implementation as this is currently very limited in functionality and I have no idea how the custom parts will be used by folks
{"ContainerCustomPart.CustomOne|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomOne|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomOne|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomOne.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomOne|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomOne.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomTwo|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomTwo|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomTwo|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomTwo.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomTwo|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomTwo.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomThree|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == -1*/))},
{"ContainerCustomPart.CustomThree|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == 1*/))},
{"ContainerCustomPart.CustomThree|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomThree.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"ContainerCustomPart.CustomThree|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<ContainerCustomPartRecord>(r => r.CustomThree.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomOne|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomOne|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomOne.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomOne|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomOne.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomOne|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomOne.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomTwo|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomTwo|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomTwo.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomTwo|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomTwo.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomTwo|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomTwo.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomThree|<", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == -1*/))},
{"CustomPropertiesPart.CustomThree|>", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => true /* CompareTo is not implemented - r.CustomThree.CompareTo(s) == 1*/))},
{"CustomPropertiesPart.CustomThree|=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomThree.Equals(s, StringComparison.OrdinalIgnoreCase)))},
{"CustomPropertiesPart.CustomThree|^=", new Func<IContentQuery<ContentItem>, string, IContentQuery<ContentItem>>((q, s) => q.Where<CustomPropertiesPartRecord>(r => r.CustomThree.StartsWith(s, StringComparison.OrdinalIgnoreCase)))},
};
}
}

View File

@@ -25,7 +25,7 @@ namespace Orchard.Core.Containers {
.Column<string>("FilterByOperator")
.Column<string>("FilterByValue"));
SchemaBuilder.CreateTable("ContainerCustomPartRecord",
SchemaBuilder.CreateTable("CustomPropertiesPartRecord",
table => table
.ContentPartRecord()
.Column<string>("CustomOne")
@@ -41,7 +41,7 @@ namespace Orchard.Core.Containers {
ContentDefinitionManager.AlterPartDefinition("ContainerPart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("ContainablePart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("ContainerCustomPart", builder => builder.Attachable());
ContentDefinitionManager.AlterPartDefinition("CustomPropertiesPart", builder => builder.Attachable());
return 1;
}

View File

@@ -2,10 +2,10 @@
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Containers.Models {
public class ContainerCustomPart : ContentPart<ContainerCustomPartRecord> {
public class CustomPropertiesPart : ContentPart<CustomPropertiesPartRecord> {
}
public class ContainerCustomPartRecord : ContentPartRecord {
public class CustomPropertiesPartRecord : ContentPartRecord {
public virtual string CustomOne { get; set; }
public virtual string CustomTwo { get; set; }
public virtual string CustomThree { get; set; }

View File

@@ -7,7 +7,7 @@
-->
<Place Parts_Containable_Edit="Content:before.3"/>
<Place Parts_Container_Edit="Content:5"/>
<Place Parts_ContainerCustom_Edit="Content:5"/>
<Place Parts_CustomProperties_Edit="Content:5"/>
<Place Parts_ContainerWidget_Edit="Content:5"/>
<Place Parts_Container_SiteSettings="Content:10"/>
<Place Parts_ContainerWidget="Content"/>

View File

@@ -6,9 +6,9 @@
@Html.SelectOption(Model.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Record.OrderByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select id="@Html.FieldIdFor(m => m.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Record.OrderByDirection)">
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)

View File

@@ -19,9 +19,9 @@
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.OrderByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select title="@T("Order direction")" id="@Html.FieldIdFor(m => m.Part.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Part.Record.OrderByDirection)">
@Html.SelectOption(Model.Part.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)
@@ -39,9 +39,9 @@
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "RoutePart.Title", T("Title").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "RoutePart.Slug", T("Slug").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "ContainerCustomPart.CustomThree", T("Custom 3").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomOne", T("Custom 1").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomTwo", T("Custom 2").Text)
@Html.SelectOption(Model.Part.Record.FilterByProperty, "CustomPropertiesPart.CustomThree", T("Custom 3").Text)
</select>
<select title="@T("Filter operator")" id="@Html.FieldIdFor(m => m.Part.Record.FilterByOperator)" name="@Html.FieldNameFor(m => m.Part.Record.FilterByOperator)">
@Html.SelectOption(Model.Part.Record.FilterByOperator, "=", T("is equal to").Text)

View File

@@ -1,4 +1,4 @@
@model Orchard.Core.Containers.Models.ContainerCustomPart
@model Orchard.Core.Containers.Models.CustomPropertiesPart
<fieldset>
@Html.LabelFor(m => m.Record.CustomOne, T("Custom One"))
@Html.EditorFor(m => m.Record.CustomOne)

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -71,7 +71,7 @@
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
<Compile Include="Containers\ContainersPathConstraint.cs" />
<Compile Include="Containers\Drivers\ContainerWidgetPartDriver.cs" />
<Compile Include="Containers\Drivers\ContainerCustomPartDriver.cs" />
<Compile Include="Containers\Drivers\CustomPropertiesDriver.cs" />
<Compile Include="Containers\Extensions\ContentQueryExtensions.cs" />
<Compile Include="Containers\Migrations.cs" />
<Compile Include="Containers\Models\ContainablePart.cs" />
@@ -79,7 +79,7 @@
<Compile Include="Common\Shapes.cs" />
<Compile Include="Common\Fields\TextField.cs" />
<Compile Include="Containers\Models\ContainerWidgetPart.cs" />
<Compile Include="Containers\Models\ContainerCustomPart.cs" />
<Compile Include="Containers\Models\CustomPropertiesPart.cs" />
<Compile Include="Containers\Models\OrderByDirection.cs" />
<Compile Include="Containers\Routes.cs" />
<Compile Include="Containers\Services\ContainersPathConstraintUpdater.cs" />
@@ -92,8 +92,6 @@
<Compile Include="Common\Services\CommonService.cs" />
<Compile Include="Common\Settings\BodySettings.cs" />
<Compile Include="Common\ViewModels\ContainerEditorViewModel.cs" />
<Compile Include="Common\ViewModels\TextContentFieldDisplayViewModel.cs" />
<Compile Include="Common\ViewModels\TextContentFieldEditorViewModel.cs" />
<Compile Include="Contents\Controllers\ItemController.cs" />
<Compile Include="Contents\Drivers\ContentsDriver.cs" />
<Compile Include="Contents\DynamicPermissions.cs" />
@@ -366,7 +364,7 @@
<Content Include="Containers\Views\DefinitionTemplates\ContainerTypePartSettings.cshtml" />
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
<Content Include="Containers\Views\Parts\ContainerWidget.cshtml" />
<Content Include="Containers\Views\EditorTemplates\ContainerCustom.cshtml" />
<Content Include="Containers\Views\EditorTemplates\CustomProperties.cshtml" />
<Content Include="Routable\Views\Parts\RoutableTitle_Summary.cshtml" />
<Content Include="Routable\Views\Parts\RoutableTitle_SummaryAdmin.cshtml" />
</ItemGroup>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,6 +1,10 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<compilation targetFramework="4.0">
<assemblies>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -23,7 +23,7 @@ namespace Orchard.Comments.Controllers {
public Localizer T { get; set; }
[HttpPost]
[HttpPost, ValidateInput(false)]
public ActionResult Create(string returnUrl) {
if (!Services.Authorizer.Authorize(Permissions.AddComment, T("Couldn't add comment")))
return !String.IsNullOrEmpty(returnUrl)
@@ -50,8 +50,15 @@ namespace Orchard.Comments.Controllers {
CommentPart commentPart = _commentService.CreateComment(context, Services.WorkContext.CurrentSite.As<CommentSettingsPart>().Record.ModerateComments);
if (commentPart.Record.Status == CommentStatus.Pending)
Services.Notifier.Information(T("Your comment will appear after the site administrator approves it."));
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."));
}
}
}
else {
foreach (var error in ModelState.Values.SelectMany(m => m.Errors).Select( e=> e.ErrorMessage)) {

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,6 +1,6 @@
@model IEnumerable<Orchard.Comments.Models.CommentPart>
@using Orchard.Comments.Models;
@using Orchard.Utility.Extensions;
<ul class="comments">
@foreach (var comment in Model) {
<li>
@@ -13,9 +13,9 @@
</span>
</h4>
</header>
<p class="text">@comment.Record.CommentText</p>
<p class="text">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText).ReplaceNewLinesWith("<br />$1")))</p>
</article>
</li>
}
}
</ul>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -326,8 +326,8 @@ namespace Orchard.ContentTypes.Controllers {
if (partViewModel == null) {
//id passed in might be that of a type w/ no implicit field
if (typeViewModel != null) {
partViewModel = new EditPartViewModel { Name = typeViewModel.Name };
_contentDefinitionService.AddPart(new CreatePartViewModel { Name = partViewModel.Name });
partViewModel = new EditPartViewModel {Name = typeViewModel.Name};
_contentDefinitionService.AddPart(new CreatePartViewModel {Name = partViewModel.Name});
_contentDefinitionService.AddPartToType(partViewModel.Name, typeViewModel.Name);
}
else {
@@ -341,7 +341,14 @@ namespace Orchard.ContentTypes.Controllers {
return AddFieldTo(id);
}
_contentDefinitionService.AddFieldToPart(viewModel.DisplayName, viewModel.FieldTypeName, partViewModel.Name);
try {
_contentDefinitionService.AddFieldToPart(viewModel.DisplayName, viewModel.FieldTypeName, partViewModel.Name);
}
catch (Exception ex) {
Services.Notifier.Information(T("The \"{0}\" field was not added. {1}", viewModel.DisplayName, ex.Message));
Services.TransactionManager.Cancel();
return AddFieldTo(id);
}
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();

View File

@@ -210,9 +210,11 @@ namespace Orchard.ContentTypes.Services {
public void AddFieldToPart(string fieldName, string fieldTypeName, string partName) {
fieldName = SafeName(fieldName);
_contentDefinitionManager.AlterPartDefinition(partName, partBuilder =>
partBuilder.WithField(fieldName, fieldBuilder => fieldBuilder.OfType(fieldTypeName))
);
if (string.IsNullOrEmpty(fieldName)) {
throw new OrchardException(T("Fields must have a name containing no spaces or symbols."));
}
_contentDefinitionManager.AlterPartDefinition(partName,
partBuilder => partBuilder.WithField(fieldName, fieldBuilder => fieldBuilder.OfType(fieldTypeName)));
}
public void RemoveFieldFromPart(string fieldName, string partName) {

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,6 +1,9 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,6 +1,9 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -24,7 +24,7 @@
<p>@module.Description</p>}
<ul class="pageStatus" style="color:#666; margin:.6em 0 0 0;">
<li>@T("Features: {0}", MvcHtmlString.Create(string.Join(", ", module.Features.Select(f => Html.Link(string.IsNullOrEmpty(f.Name) ? f.Id : f.Name, string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), f.Id.AsFeatureId(n => T(n)))).ToString()).OrderBy(s => s).ToArray())))</li>
<li>&nbsp;&#124;&nbsp;@T("Author: {0}", !string.IsNullOrEmpty(module.Author) ? module.Author : "Unknown")</li>
<li>&nbsp;&#124;&nbsp;@T("Author: {0}", !string.IsNullOrEmpty(module.Author) ? module.Author : T("Unknown").ToString())</li>
<li>&nbsp;&#124;&nbsp;@T("Website: {0}", !string.IsNullOrEmpty(module.WebSite) ? module.WebSite : "http://orchardproject.net")</li>
</ul>
</div>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -6,6 +6,7 @@ using System.Web.Hosting;
using System.Web.Mvc;
using System.Xml.Linq;
using NuGet;
using Orchard.Environment;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData;
using Orchard.Localization;
@@ -25,16 +26,19 @@ namespace Orchard.Packaging.Controllers {
private readonly IPackagingSourceManager _packagingSourceManager;
private readonly IAppDataFolderRoot _appDataFolderRoot;
private readonly INotifier _notifier;
private readonly IHostEnvironment _hostEnvironment;
public GalleryController(
IPackageManager packageManager,
IPackagingSourceManager packagingSourceManager,
INotifier notifier,
IAppDataFolderRoot appDataFolderRoot) {
IAppDataFolderRoot appDataFolderRoot,
IHostEnvironment hostEnvironment) {
_packageManager = packageManager;
_packagingSourceManager = packagingSourceManager;
_notifier = notifier;
_appDataFolderRoot = appDataFolderRoot;
_hostEnvironment = hostEnvironment;
T = NullLocalizer.Instance;
}
@@ -60,12 +64,11 @@ namespace Orchard.Packaging.Controllers {
[HttpPost]
public ActionResult AddSource(string url) {
try {
if ( !String.IsNullOrEmpty(url) ) {
if (!String.IsNullOrEmpty(url)) {
if (!url.StartsWith("http")) {
ModelState.AddModelError("Url", T("The Url is not valid").Text);
}
}
else if ( String.IsNullOrWhiteSpace(url)) {
} else if (String.IsNullOrWhiteSpace(url)) {
ModelState.AddModelError("Url", T("Url is required").Text);
}
@@ -73,29 +76,27 @@ namespace Orchard.Packaging.Controllers {
// try to load the feed
try {
XNamespace atomns = "http://www.w3.org/2005/Atom" ;
XNamespace atomns = "http://www.w3.org/2005/Atom";
var feed = XDocument.Load(url, LoadOptions.PreserveWhitespace);
var titleNode = feed.Descendants(atomns + "title").FirstOrDefault();
if ( titleNode != null )
if (titleNode != null)
title = titleNode.Value;
if(String.IsNullOrWhiteSpace(title)) {
if (String.IsNullOrWhiteSpace(title)) {
ModelState.AddModelError("Url", T("The feed has no title.").Text);
}
}
catch {
} catch {
ModelState.AddModelError("Url", T("The url of the feed or its content is not valid.").Text);
}
if ( !ModelState.IsValid )
if (!ModelState.IsValid)
return View(new PackagingAddSourceViewModel { Url = url });
_packagingSourceManager.AddSource(title, url);
_notifier.Information(T("The feed has been added successfully."));
return RedirectToAction("Sources");
}
catch ( Exception exception ) {
} catch (Exception exception) {
_notifier.Error(T("Adding feed failed: {0}", exception.Message));
return View(new PackagingAddSourceViewModel { Url = url });
}
@@ -104,8 +105,8 @@ namespace Orchard.Packaging.Controllers {
public ActionResult Modules(int? sourceId) {
var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
var sources = selectedSource != null
? new [] { selectedSource }
var sources = selectedSource != null
? new[] { selectedSource }
: _packagingSourceManager.GetSources()
;
@@ -134,7 +135,7 @@ namespace Orchard.Packaging.Controllers {
public ActionResult Install(string packageId, string version, int sourceId, string redirectTo) {
var source = _packagingSourceManager.GetSources().Where(s => s.Id == sourceId).FirstOrDefault();
if(source == null) {
if (source == null) {
return HttpNotFound();
}
@@ -147,15 +148,30 @@ namespace Orchard.Packaging.Controllers {
return View();
}
[HttpPost, ActionName("AddTheme")]
public ActionResult AddThemePOST(string returnUrl) {
return InstallPackage(returnUrl, Request.RawUrl);
}
[HttpPost, ActionName("RemoveTheme")]
public ActionResult RemoveThemePOST(string themeId, string returnUrl, string retryUrl) {
return UninstallPackage(PackagingSourceManager.ThemesFilter + themeId, returnUrl, retryUrl);
}
public ActionResult AddModule(string returnUrl) {
return View();
}
[HttpPost, ActionName("AddModule")]
public ActionResult AddModulePOST(string returnUrl) {
// module not used for anything o2ther than display (and that only to not have object in the view 'T')
return InstallPackage(returnUrl, Request.RawUrl);
}
public ActionResult InstallPackage(string returnUrl, string retryUrl) {
try {
if (string.IsNullOrWhiteSpace(Request.Files[0].FileName)) {
if (Request.Files != null &&
Request.Files.Count > 0 &&
!string.IsNullOrWhiteSpace(Request.Files[0].FileName)) {
ModelState.AddModelError("File", T("Select a file to upload.").ToString());
}
@@ -172,16 +188,29 @@ namespace Orchard.Packaging.Controllers {
}
}
if (!string.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Modules");
return Redirect(returnUrl);
} catch (Exception exception) {
for (var scan = exception; scan != null; scan = scan.InnerException) {
for (Exception scan = exception; scan != null; scan = scan.InnerException) {
_notifier.Error(T("Uploading module package failed: {0}", exception.Message));
}
return View("AddModule");
return Redirect(retryUrl);
}
}
public ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) {
try {
_packageManager.Uninstall(id, HostingEnvironment.MapPath("~/"));
_notifier.Information(T("Uninstalled package \"{0}\"", id));
return Redirect(returnUrl);
} catch (Exception exception) {
for (Exception scan = exception; scan != null; scan = scan.InnerException) {
_notifier.Error(T("Uninstall failed: {0}", exception.Message));
}
return Redirect(retryUrl);
}
}
}

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,9 +1,9 @@
using System;
using System.IO;
using System.Web.Hosting;
using NuGet;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.AppData;
using Orchard.Localization;
using Orchard.UI.Notify;
using NuGetPackageManager = NuGet.PackageManager;
@@ -12,17 +12,15 @@ namespace Orchard.Packaging.Services {
[OrchardFeature("PackagingServices")]
public class PackageInstaller : IPackageInstaller {
private const string PackagesPath = "packages";
private const string SolutionFilename = "Orchard.sln";
private readonly INotifier _notifier;
private readonly IExtensionManager _extensionManager;
private readonly IAppDataFolderRoot _appDataFolderRoot;
public PackageInstaller(INotifier notifier,
IExtensionManager extensionManager,
IAppDataFolderRoot appDataFolderRoot) {
IExtensionManager extensionManager) {
_notifier = notifier;
_extensionManager = extensionManager;
_appDataFolderRoot = appDataFolderRoot;
T = NullLocalizer.Instance;
}
@@ -57,22 +55,23 @@ namespace Orchard.Packaging.Services {
bool installed = false;
// if we can access the parent directory, and the solution is inside, NuGet-install the package here
var installedPackagesPath = Path.Combine(_appDataFolderRoot.RootFolder, PackagesPath);
try
{
var packageManager = new NuGetPackageManager(
string solutionPath;
var installedPackagesPath = String.Empty;
if (TryGetSolutionPath(applicationPath, out solutionPath)) {
installedPackagesPath = Path.Combine(solutionPath, PackagesPath);
try {
var packageManager = new NuGetPackageManager(
packageRepository,
new DefaultPackagePathResolver(location),
new PhysicalFileSystem(installedPackagesPath) { Logger = logger }
) { Logger = logger };
new PhysicalFileSystem(installedPackagesPath) {Logger = logger}
) {Logger = logger};
packageManager.InstallPackage(package, ignoreDependencies: true);
installed = true;
}
catch
{
// installing the package in the appdata folder failed
packageManager.InstallPackage(package, true);
installed = true;
}
catch {
// installing the package at the solution level failed
}
}
// if the package got installed successfully, use it, otherwise use the previous repository
@@ -95,7 +94,7 @@ namespace Orchard.Packaging.Services {
{
ExtensionName = package.Title ?? package.Id,
ExtensionVersion = package.Version.ToString(),
ExtensionType = package.Id.StartsWith("Orchard.Theme") ? DefaultExtensionTypes.Theme : DefaultExtensionTypes.Module,
ExtensionType = package.Id.StartsWith(PackagingSourceManager.ThemesFilter) ? DefaultExtensionTypes.Theme : DefaultExtensionTypes.Module,
ExtensionPath = applicationPath
};
}
@@ -104,26 +103,58 @@ namespace Orchard.Packaging.Services {
// this logger is used to render NuGet's log on the notifier
var logger = new NugetLogger(_notifier);
var installedPackagesPath = Path.Combine(_appDataFolderRoot.RootFolder, PackagesPath);
var sourcePackageRepository = new LocalPackageRepository(installedPackagesPath);
var project = new FileBasedProjectSystem(applicationPath) { Logger = logger };
var projectManager = new ProjectManager(
sourcePackageRepository,
new DefaultPackagePathResolver(installedPackagesPath),
project,
new ExtensionReferenceRepository(project, sourcePackageRepository, _extensionManager)
) { Logger = logger };
string solutionPath;
// if we can access the parent directory, and the solution is inside, NuGet-uninstall the package here
if (TryGetSolutionPath(applicationPath, out solutionPath)) {
var installedPackagesPath = Path.Combine(solutionPath, PackagesPath);
var sourcePackageRepository = new LocalPackageRepository(installedPackagesPath);
var project = new FileBasedProjectSystem(applicationPath) { Logger = logger };
var projectManager = new ProjectManager(
sourcePackageRepository,
new DefaultPackagePathResolver(installedPackagesPath),
project,
new ExtensionReferenceRepository(project, sourcePackageRepository, _extensionManager)
) { Logger = logger };
// add the package to the project
projectManager.RemovePackageReference(packageId);
// add the package to the project
projectManager.RemovePackageReference(packageId);
var packageManager = new NuGetPackageManager(
var packageManager = new NuGetPackageManager(
sourcePackageRepository,
new DefaultPackagePathResolver(applicationPath),
new PhysicalFileSystem(installedPackagesPath) { Logger = logger }
) { Logger = logger };
) { Logger = logger };
packageManager.UninstallPackage(packageId);
packageManager.UninstallPackage(packageId);
} else {
// otherwise delete the folder
string extensionPath = packageId.StartsWith(PackagingSourceManager.ThemesFilter)
? "~/Themes/" + packageId.Substring(PackagingSourceManager.ThemesFilter.Length)
: "~/Modules/" + packageId.Substring(PackagingSourceManager.ModulesFilter.Length);
string extensionFullPath = HostingEnvironment.MapPath(extensionPath);
if (Directory.Exists(extensionFullPath)) {
Directory.Delete(extensionFullPath, true);
}
else {
throw new OrchardException(T("Package not found: ", packageId));
}
}
}
private bool TryGetSolutionPath(string applicationPath, out string parentPath) {
try {
parentPath = Directory.GetParent(applicationPath).Parent.FullName;
var solutionPath = Path.Combine(parentPath, SolutionFilename);
return File.Exists(solutionPath);
}
catch {
// Either solution does not exist or we are running under medium trust
parentPath = null;
return false;
}
}
}
}

View File

@@ -46,6 +46,7 @@ namespace Orchard.Packaging.Services {
public void Uninstall(string packageId, string applicationPath) {
_packageExpander.Uninstall(packageId, applicationPath);
}
#endregion
}
}

View File

@@ -10,8 +10,8 @@ using Orchard.Packaging.Models;
namespace Orchard.Packaging.Services {
[OrchardFeature("Gallery")]
public class PackagingSourceManager : IPackagingSourceManager {
private const string ModulesFilter = "Orchard.Module.";
private const string ThemesFilter = "Orchard.Theme.";
public const string ModulesFilter = "Orchard.Module.";
public const string ThemesFilter = "Orchard.Theme.";
private readonly IRepository<PackagingSource> _packagingSourceRecordRepository;

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,10 +1,11 @@
<h1>@Html.TitleForPage(T("Install Theme").ToString())</h1>
@using (Html.BeginForm("Install", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" })) {
@Html.ValidationSummary()
<fieldset>
<label for="ThemeZipPath">@T("File Path to the zip file:")</label>
<input id="ThemeZipPath" name="ThemeZipPath" type="file" class="text" value="@T("Browse")" size="64" /><br />
<button class="primaryAction" type="submit">@T("Install")</button>
@Html.AntiForgeryTokenOrchard()
</fieldset>
}
@{
<h1>@Html.TitleForPage(T("Install a Theme").ToString())</h1>
using (Html.BeginFormAntiForgeryPost(Url.Action("AddTheme", new { area = "Orchard.Gallery" }), FormMethod.Post, new { enctype = "multipart/form-data" })) {
Html.ValidationSummary();
<fieldset>
<label for="ModulePackage">@T("Theme Package")</label>
<input type="file" id="ThemePackage" size="64" name="ThemePackage" />
</fieldset>
<button type="submit" class="primaryAction">@T("Install")</button>
}
}

View File

@@ -1,6 +1,9 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<!-- iis6 - for any request in this location, return via managed static file handler -->

View File

@@ -1,5 +1,8 @@
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
</httpHandlers>

Some files were not shown because too many files have changed in this diff Show More