--HG--
branch : 1.x
This commit is contained in:
Nathan Heskew
2011-04-07 15:59:37 -07:00
54 changed files with 640 additions and 348 deletions

View File

@@ -276,13 +276,18 @@
$(StageFolder)\**\Modules\Lucene\**;
$(StageFolder)\**\Modules\Orchard.ArchiveLater\**;
$(StageFolder)\**\Modules\Orchard.CodeGeneration\**;
$(StageFolder)\**\Modules\Orchard.DesignerTools\**;
$(StageFolder)\**\Modules\Orchard.Email\**;
$(StageFolder)\**\Modules\Orchard.Experimental\**;
$(StageFolder)\**\Modules\Orchard.ImportExport\**;
$(StageFolder)\**\Modules\Orchard.Indexing\**;
$(StageFolder)\**\Modules\Orchard.MediaPicker\**;
$(StageFolder)\**\Modules\Orchard.Migrations\**;
$(StageFolder)\**\Modules\Orchard.MultiTenancy\**;
$(StageFolder)\**\Modules\Orchard.Recipes\**;
$(StageFolder)\**\Modules\Orchard.Scripting.Dlr\**;
$(StageFolder)\**\Modules\Orchard.Search\**;
$(StageFolder)\**\Modules\Orchard.Warmup\**;
" />
<MsDeploy-Folder-Input Include="$(StageFolder)\**\*" Exclude="$(StageFolder)\**\bin\**\*.xml;@(MsDeploy-Exclude-Modules)" />
@@ -375,13 +380,18 @@
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Lucene &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.ArchiveLater &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.CodeGeneration &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.DesignerTools &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Email &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Experimental &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.ImportExport &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Indexing &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.MediaPicker &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Migrations &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.MultiTenancy &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Recipes &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Scripting.Dlr &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Search &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
<Exec Command="&quot;$(GalleryFolder)\bin\Orchard.exe&quot; package create Orchard.Warmup &quot;$(GalleryArtifactFolder)&quot;" WorkingDirectory="$(GalleryFolder)"/>
</Target>
<!-- ValidateProjectFiles-->

View File

@@ -222,6 +222,23 @@ namespace Orchard.Specs.Bindings {
WhenIGoTo(urlPath);
}
[When(@"I follow ""([^""]+)"" where class name has ""([^""]+)""")]
public void WhenIFollowClass(string linkText, string className) {
var link = _doc.DocumentNode
.SelectNodes("//a[@href]").Where(elt =>
(elt.InnerText == linkText ||
(elt.Attributes["title"] != null && elt.Attributes["title"].Value == linkText)) &&
elt.Attributes["class"].Value.IndexOf(className, StringComparison.OrdinalIgnoreCase) != -1).SingleOrDefault();
if (link == null) {
throw new InvalidOperationException(string.Format("Could not find an anchor with matching text '{0}' and class '{1}'. Document: {2}", linkText, className, _doc.DocumentNode.InnerHtml));
}
var href = link.Attributes["href"].Value;
var urlPath = HttpUtility.HtmlDecode(href);
WhenIGoTo(urlPath);
}
[When(@"I fill in")]
public void WhenIFillIn(Table table) {
var inputs = _doc.DocumentNode

View File

@@ -17,7 +17,7 @@ Scenario: I can create a new blog and blog post
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -39,7 +39,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -50,7 +50,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
And I should see "Hi there."
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -61,7 +61,7 @@ Scenario: I can create a new blog with multiple blog posts each with the same ti
And I should see "Hi there, again."
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -83,7 +83,7 @@ Scenario: I can create a new blog and blog post and when I change the slug of th
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
When I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -114,7 +114,7 @@ Scenario: When viewing a blog the user agent is given an RSS feed of the blog's
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |
@@ -151,7 +151,7 @@ Scenario: The virtual path of my installation when not at the root is reflected
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
Then I should see "<span>http\://localhost/OrchardLocal/my-blog/</span>"
Scenario: The virtual path of my installation when at the root is reflected in the URL example for the slug field when creating a blog or blog post
@@ -164,7 +164,7 @@ Scenario: The virtual path of my installation when at the root is reflected in t
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
Then I should see "<span>http\://localhost/my-blog/</span>"
Scenario: I set my blog to be the content for the home page and the posts for the blog be rooted to the app
@@ -177,7 +177,7 @@ Scenario: I set my blog to be the content for the home page and the posts for th
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |

View File

@@ -1,7 +1,7 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.4.0.0
// SpecFlow Version:1.5.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -14,7 +14,7 @@ namespace Orchard.Specs
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.5.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Blog")]
@@ -97,7 +97,7 @@ this.ScenarioSetup(scenarioInfo);
#line 19
testRunner.And("I follow \"My Blog\"");
#line 20
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -157,7 +157,7 @@ this.ScenarioSetup(scenarioInfo);
#line 41
testRunner.And("I follow \"My Blog\"");
#line 42
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -183,7 +183,7 @@ this.ScenarioSetup(scenarioInfo);
#line 52
testRunner.And("I follow \"My Blog\"");
#line 53
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -209,7 +209,7 @@ this.ScenarioSetup(scenarioInfo);
#line 63
testRunner.And("I follow \"My Blog\"");
#line 64
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -270,7 +270,7 @@ this.ScenarioSetup(scenarioInfo);
#line 85
testRunner.And("I follow \"My Blog\"");
#line 86
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -349,7 +349,7 @@ this.ScenarioSetup(scenarioInfo);
#line 116
testRunner.And("I follow \"My Blog\"");
#line 117
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table11 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -452,7 +452,7 @@ this.ScenarioSetup(scenarioInfo);
#line 153
testRunner.And("I follow \"My Blog\"");
#line 154
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line 155
testRunner.Then("I should see \"<span>http\\://localhost/OrchardLocal/my-blog/</span>\"");
#line hidden
@@ -490,7 +490,7 @@ this.ScenarioSetup(scenarioInfo);
#line 166
testRunner.And("I follow \"My Blog\"");
#line 167
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line 168
testRunner.Then("I should see \"<span>http\\://localhost/my-blog/</span>\"");
#line hidden
@@ -529,7 +529,7 @@ this.ScenarioSetup(scenarioInfo);
#line 179
testRunner.And("I follow \"My Blog\"");
#line 180
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
"name",

View File

@@ -12,7 +12,7 @@ Scenario: HTML markup in any given comment is encoded
And I hit "Save"
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post"
And I follow "New Post" where class name has "primaryAction"
And I fill in
| name | value |
| Routable.Title | My Post |

View File

@@ -1,7 +1,7 @@
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.4.0.0
// SpecFlow Version:1.5.0.0
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -14,7 +14,7 @@ namespace Orchard.Specs
using TechTalk.SpecFlow;
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.4.0.0")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.5.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Comments")]
@@ -80,7 +80,7 @@ this.ScenarioSetup(scenarioInfo);
#line 14
testRunner.And("I follow \"My Blog\"");
#line 15
testRunner.And("I follow \"New Post\"");
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",

View File

@@ -1,11 +1,11 @@
Feature: Lists
In order to add new lists to my site
As an administrator
I want to create lists
Scenario: I can create a new list
Given I have installed Orchard
When I go to "Admin/Contents/Create/List"
Feature: Lists
In order to add new lists to my site
As an administrator
I want to create lists
Scenario: I can create a new list
Given I have installed Orchard
When I go to "Admin/Contents/Create/List"
And I fill in
| name | value |
| Routable.Title | MyList |
@@ -13,25 +13,25 @@ Scenario: I can create a new list
And I go to "Admin/Contents/List/List"
Then I should see "MyList"
Scenario: I can add content items to a list
Given I have installed Orchard
And I have a containable content type "MyType"
When I go to "Admin/Contents/Create/List"
Scenario: I can add content items to a list
Given I have installed Orchard
And I have a containable content type "MyType"
When I go to "Admin/Contents/Create/List"
And I fill in
| name | value |
| Routable.Title | MyList |
And I hit "Save"
And I go to "Admin/Contents/List/List"
Then I should see "MyList"
When I follow "Contained Items"
Then I should see "The 'MyList' List has no content items."
When I follow "Create New Content" where href has "ReturnUrl"
Then I should see "MyType"
When I follow "MyType" where href has "ReturnUrl"
When I follow "Contained Items"
Then I should see "The 'MyList' List has no content items."
When I follow "Create New Content" where href has "ReturnUrl"
Then I should see "MyType"
When I follow "MyType" where href has "ReturnUrl"
And I fill in
| name | value |
| Routable.Title | MyContentItem |
And I hit "Save"
And I am redirected
Then I should see "Manage Content for MyList"
And I should see "MyContentItem"
And I am redirected
Then I should see "Manage MyList"
And I should see "MyContentItem"

View File

@@ -30,7 +30,8 @@ namespace Orchard.Specs
public virtual void FeatureSetup()
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Lists", "In order to add new lists to my site\nAs an administrator\nI want to create lists", GenerationTargetLanguage.CSharp, ((string[])(null)));
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Lists", "In order to add new lists to my site\r\nAs an administrator\r\nI want to create lists" +
"", GenerationTargetLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
@@ -60,9 +61,9 @@ namespace Orchard.Specs
#line 6
this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 8
testRunner.When("I go to \"Admin/Contents/Create/List\"");
testRunner.When("I go to \"Admin/Contents/Create/List\"");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -90,11 +91,11 @@ this.ScenarioSetup(scenarioInfo);
#line 16
this.ScenarioSetup(scenarioInfo);
#line 17
testRunner.Given("I have installed Orchard");
testRunner.Given("I have installed Orchard");
#line 18
testRunner.And("I have a containable content type \"MyType\"");
testRunner.And("I have a containable content type \"MyType\"");
#line 19
testRunner.When("I go to \"Admin/Contents/Create/List\"");
testRunner.When("I go to \"Admin/Contents/Create/List\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -111,15 +112,15 @@ this.ScenarioSetup(scenarioInfo);
#line 25
testRunner.Then("I should see \"MyList\"");
#line 26
testRunner.When("I follow \"Contained Items\"");
testRunner.When("I follow \"Contained Items\"");
#line 27
testRunner.Then("I should see \"The \'MyList\' List has no content items.\"");
testRunner.Then("I should see \"The \'MyList\' List has no content items.\"");
#line 28
testRunner.When("I follow \"Create New Content\" where href has \"ReturnUrl\"");
testRunner.When("I follow \"Create New Content\" where href has \"ReturnUrl\"");
#line 29
testRunner.Then("I should see \"MyType\"");
testRunner.Then("I should see \"MyType\"");
#line 30
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
testRunner.When("I follow \"MyType\" where href has \"ReturnUrl\"");
#line hidden
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@@ -132,11 +133,11 @@ this.ScenarioSetup(scenarioInfo);
#line 34
testRunner.And("I hit \"Save\"");
#line 35
testRunner.And("I am redirected");
testRunner.And("I am redirected");
#line 36
testRunner.Then("I should see \"Manage Content for MyList\"");
testRunner.Then("I should see \"Manage MyList\"");
#line 37
testRunner.And("I should see \"MyContentItem\"");
testRunner.And("I should see \"MyContentItem\"");
#line hidden
testRunner.CollectScenarioErrors();
}

View File

@@ -7,7 +7,7 @@ Scenario: Media admin is available
Given I have installed Orchard
And I have installed "Orchard.Media"
When I go to "admin/media"
Then I should see "Manage Media Folders"
Then I should see "Media"
And the status should be 200 "OK"
Scenario: Creating a folder
@@ -19,7 +19,7 @@ Scenario: Creating a folder
| Name | Hello World |
And I hit "Save"
And I am redirected
Then I should see "Manage Media Folders"
Then I should see "Media"
And I should see "Hello World"
And the status should be 200 "OK"
@@ -28,6 +28,6 @@ Scenario: Limited access
And I have installed "Orchard.Media"
When I go to "admin/media/edit?name=..\..\bin&mediaPath=..\..\bin"
And I am redirected
Then I should see "Manage Media Folders"
Then I should see "Media"
And I should see "Editing failed: Invalid path"
And the status should be 200 "OK"

View File

@@ -67,7 +67,7 @@ this.ScenarioSetup(scenarioInfo);
#line 9
testRunner.When("I go to \"admin/media\"");
#line 10
testRunner.Then("I should see \"Manage Media Folders\"");
testRunner.Then("I should see \"Media\"");
#line 11
testRunner.And("the status should be 200 \"OK\"");
#line hidden
@@ -101,7 +101,7 @@ this.ScenarioSetup(scenarioInfo);
#line 21
testRunner.And("I am redirected");
#line 22
testRunner.Then("I should see \"Manage Media Folders\"");
testRunner.Then("I should see \"Media\"");
#line 23
testRunner.And("I should see \"Hello World\"");
#line 24
@@ -126,7 +126,7 @@ this.ScenarioSetup(scenarioInfo);
#line 30
testRunner.And("I am redirected");
#line 31
testRunner.Then("I should see \"Manage Media Folders\"");
testRunner.Then("I should see \"Media\"");
#line 32
testRunner.And("I should see \"Editing failed: Invalid path\"");
#line 33

View File

@@ -7,14 +7,14 @@
Scenario: There is only one user by default
Given I have installed Orchard
When I go to "admin/users"
Then I should see "Manage Users"
Then I should see "Users"
And I should see "<a[^>]*>admin</a>"
@management
Scenario: I can create a new user
Given I have installed Orchard
When I go to "admin/users"
Then I should see "Manage Users"
Then I should see "Users"
When I follow "Add a new user"
And I fill in
| name | value |

View File

@@ -2,7 +2,7 @@
// <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.5.0.0
// Runtime Version:4.0.30319.225
// Runtime Version:4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -67,7 +67,7 @@ this.ScenarioSetup(scenarioInfo);
#line 9
testRunner.When("I go to \"admin/users\"");
#line 10
testRunner.Then("I should see \"Manage Users\"");
testRunner.Then("I should see \"Users\"");
#line 11
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
#line hidden
@@ -88,7 +88,7 @@ this.ScenarioSetup(scenarioInfo);
#line 16
testRunner.When("I go to \"admin/users\"");
#line 17
testRunner.Then("I should see \"Manage Users\"");
testRunner.Then("I should see \"Users\"");
#line 18
testRunner.When("I follow \"Add a new user\"");
#line hidden

View File

@@ -1,4 +1,6 @@
using System;
using System.Globalization;
using System.Threading;
using System.Xml.Linq;
using Autofac;
using Moq;
@@ -122,5 +124,18 @@ namespace Orchard.Tests.Modules.Users.Services {
Assert.That(username, Is.EqualTo("foo"));
Assert.That(validateByUtc, Is.GreaterThan(_clock.UtcNow));
}
[Test]
public void VerifyUserUnicityTurkishTest() {
CultureInfo turkishCulture = new CultureInfo("tr-TR");
Thread.CurrentThread.CurrentCulture = turkishCulture;
// Create user lower case
_membershipService.CreateUser(new CreateUserParams("admin", "66554321", "foo@bar.com", "", "", true));
_container.Resolve<IOrchardServices>().ContentManager.Flush();
// Verify unicity with upper case which with turkish coallition would yeld admin with an i without the dot and therefore generate a different user name
Assert.That(_userService.VerifyUserUnicity("ADMIN", "differentfoo@bar.com"), Is.False); // should fail
}
}
}

View File

@@ -273,6 +273,7 @@
<Compile Include="Stubs\StubVirtualPathMonitor.cs" />
<Compile Include="Stubs\StubCacheManager.cs" />
<Compile Include="Stubs\StubWebSiteFolder.cs" />
<Compile Include="UI\Resources\ResourceManagerTests.cs" />
<Compile Include="UI\ShapeTests.cs" />
<Compile Include="Utility\ContainerExtensions.cs" />
<Compile Include="Environment\TestDependencies\TestDependency.cs" />

View File

@@ -0,0 +1,133 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Autofac;
using NUnit.Framework;
using Orchard.DisplayManagement.Implementation;
using Orchard.Tests.Stubs;
using Orchard.UI.Admin;
using Orchard.UI.Resources;
namespace Orchard.Tests.UI.Resources {
[TestFixture]
public class ResourceManagerTests {
private IContainer _container;
private IResourceManager _resourceManager;
private TestManifestProvider _testManifest;
private string _appPath = "/AppPath/";
private class TestManifestProvider : IResourceManifestProvider {
public Action<ResourceManifest> DefineManifest { get; set; }
public TestManifestProvider() {
}
public void BuildManifests(ResourceManifestBuilder builder) {
var manifest = builder.Add();
if (DefineManifest != null) {
DefineManifest(manifest);
}
}
}
private void VerifyPaths(string resourceType, RequireSettings defaultSettings, string expectedPaths) {
defaultSettings = defaultSettings ?? new RequireSettings();
var requiredResources = _resourceManager.BuildRequiredResources(resourceType);
var renderedResources = string.Join(",", requiredResources.Select(context => context.GetResourceUrl(defaultSettings, _appPath)).ToArray());
Assert.That(renderedResources, Is.EqualTo(expectedPaths));
}
[SetUp]
public void Init() {
var builder = new ContainerBuilder();
builder.RegisterType<ResourceManager>().As<IResourceManager>();
builder.RegisterType<TestManifestProvider>().As<IResourceManifestProvider>().SingleInstance();
_container = builder.Build();
_resourceManager = _container.Resolve<IResourceManager>();
_testManifest = _container.Resolve<IResourceManifestProvider>() as TestManifestProvider;
}
[Test]
public void ReleasePathIsTheDefaultPath() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", null, "script1.min.js");
}
[Test]
public void DebugPathIsUsedWithDebugMode() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", new RequireSettings { DebugMode = true }, "script1.js");
}
[Test]
public void ReleasePathIsUsedWhenNoDebugPath() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", new RequireSettings { DebugMode = true }, "script1.min.js");
}
[Test]
public void DefaultSettingsAreOverriddenByUseDebugMode() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
};
_resourceManager.Require("script", "Script1").UseDebugMode();
VerifyPaths("script", new RequireSettings { DebugMode = false }, "script1.js");
}
[Test]
public void CdnPathIsUsedInCdnMode() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.js").SetCdn("http://cdn/script1.min.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", new RequireSettings { CdnMode = true }, "http://cdn/script1.min.js");
}
[Test]
public void CdnDebugPathIsUsedInCdnModeAndDebugMode() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.js").SetCdn("http://cdn/script1.min.js", "http://cdn/script1.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", new RequireSettings { CdnMode = true, DebugMode = true }, "http://cdn/script1.js");
}
[Test]
public void DebugPathIsUsedInCdnModeAndDebugModeAndThereIsNoCdnDebugPath() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js").SetCdn("http://cdn/script1.min.js");
};
_resourceManager.Require("script", "Script1");
VerifyPaths("script", new RequireSettings { CdnMode = true, DebugMode = true }, "script1.js");
}
[Test]
public void DependenciesAreAutoIncluded() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js");
m.DefineResource("script", "Script2").SetUrl("script2.min.js").SetDependencies("Script1");
};
_resourceManager.Require("script", "Script2");
VerifyPaths("script", null, "script1.min.js,script2.min.js");
}
[Test]
public void DependenciesAssumeTheirParentUseDebugModeSetting() {
_testManifest.DefineManifest = m => {
m.DefineResource("script", "Script1").SetUrl("script1.min.js", "script1.js");
m.DefineResource("script", "Script2").SetUrl("script2.min.js", "script2.js").SetDependencies("Script1");
};
_resourceManager.Require("script", "Script2").UseDebugMode();
VerifyPaths("script", new RequireSettings { DebugMode = false }, "script1.js,script2.js");
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.Drivers;
using Orchard.Core.Common.Models;
using Orchard.Core.Containers.Models;
using Orchard.Core.Containers.ViewModels;
using Orchard.Localization;
@@ -27,7 +28,7 @@ namespace Orchard.Core.Containers.Drivers {
return ContentShape(
"Parts_Containable_Edit",
() => {
var commonPart = part.As<ICommonPart>();
var commonPart = part.As<CommonPart>();
var model = new ContainableViewModel();
if (commonPart != null && commonPart.Container != null) {
@@ -37,10 +38,12 @@ namespace Orchard.Core.Containers.Drivers {
if (updater != null) {
var oldContainerId = model.ContainerId;
updater.TryUpdateModel(model, "Containable", null, null);
if (oldContainerId != model.ContainerId)
if (oldContainerId != model.ContainerId) {
if (commonPart != null) {
commonPart.Container = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
var containerItem = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
commonPart.Record.Container = containerItem == null ? null : containerItem.Record;
}
}
}
// note: string.isnullorempty not being recognized by linq-to-nhibernate hence the inline or
@@ -50,7 +53,7 @@ namespace Orchard.Core.Containers.Drivers {
var listItems = new[] { new SelectListItem { Text = T("(None)").Text, Value = "0" } }
.Concat(containers.Select(x => new SelectListItem {
Value = Convert.ToString(x.Id),
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + x.As<IRoutableAspect>().Title,
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + _contentManager.GetItemMetadata(x.ContentItem).DisplayText,
Selected = x.Id == model.ContainerId,
}))
.ToList();

View File

@@ -1,4 +1,9 @@
@Display(Model.ContentItems)
@{
IEnumerable<object> items = Model.ContentItems;
Model.ContentItems.Classes.Add("content-items");
Model.ContentItems.Classes.Add("list-items");
}
@Display(items)
@if (Model.ShowPager) {
@Display(Model.Pager)
}

View File

@@ -1,7 +1,6 @@
@using Orchard.ContentManagement
@{
GroupInfo groupInfo = Model.GroupInfo;
Layout.Title = (groupInfo != null ? T("Settings for {0}", groupInfo.Name) : T("General Settings")).ToString();
Layout.Title = T("Settings").ToString();
}
@using (Html.BeginFormAntiForgeryPost()) {

View File

@@ -8,7 +8,7 @@
}, "Id", "Text", (int)Model.ResourceDebugMode);
}
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("General")</legend>
<div>
<label for="SiteName">@T("Site name")</label>
@Html.EditorFor(m => m.SiteName)

View File

@@ -2,7 +2,7 @@
@using Orchard.Comments.Models;
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("Comments")</legend>
<div>
@Html.EditorFor(m => m.ModerateComments)
<label class="forcheckbox" for="CommentSettings_ModerateComments">@T("Comments must be approved before they appear")</label>

View File

@@ -4,7 +4,6 @@ if (!window.shapeTracingMetadataHost) {
window.shapeTracingMetadataHost.placement = {
'n/a': 'n/a'
};
window.shapeTracingMetadataHost.references = {};
}
jQuery(function ($) {
@@ -37,7 +36,7 @@ jQuery(function ($) {
var previousSize = 0;
// represents the arrow to add to any collpasible container
var glyph = $('<span class="expando-glyph-container closed"><span class="expando-glyph"></span>&#8203;</span>');
var glyph = '<span class="expando-glyph-container closed"><span class="expando-glyph"></span>&#8203;</span>';
// ensure the ghost has always the same size as the container
// and the container is always positionned correctly
@@ -118,7 +117,7 @@ jQuery(function ($) {
$('#shape-tracing-resize-handle').addClass('ui-resizable-handle ui-resizable-n');
shapeTracingContainer.resizable({
handles: { n: '#shape-tracing-resize-handle' },
grid: 20, // mitigates the number of calls to syncResize(), and aligns to the line height
grid: 20, // mitigates the number of calls to syncResize()
resize: function () { shapeTracingEnabled = false },
stop: function () { shapeTracingEnabled = true }
});
@@ -192,27 +191,34 @@ jQuery(function ($) {
shapeTracingWindowTree.append(shapes);
// add the expand/collapse logic to the shapes tree
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingWindowTree.find('li:has(ul:has(li))').prepend($(glyph));
// collapse all sub uls
shapeTracingWindowTree.find('ul ul').toggle(false);
// expands a list of shapes in the tree
var openExpando = function (expando) {
if (expando.hasClass("closed") || expando.hasClass("closing")) {
expando.siblings('ul').slideDown(100, function () { expando.removeClass("opening").removeClass("closed").addClass("open"); });
expando.addClass("opening");
if (expando.hasClass("closed")) {
expando.siblings('ul').toggle(true);
expando.removeClass("closed").addClass("open");
}
}
// collapses a list of shapes in the tree
var closeExpando = function (expando) {
if (!expando.hasClass("closed") && !expando.hasClass("closing")) {
expando.siblings('ul').slideUp(100, function () { expando.removeClass("closing").removeClass("open").addClass("closed"); });
expando.addClass("closing");
if (expando.hasClass("open")) {
expando.siblings('ul').toggle(false);
expando.removeClass("open").addClass("closed");
}
}
shapeTracingWindow.add(shapeTracingResizeHandle).hover(function () {
shapeTracingOverlay.hide();
}, function () {
shapeTracingOverlay.show();
}
);
//create an overlay on shapes' descendants
var overlayTarget = null;
$('[shape-id]').add(shapeTracingOverlay).mousemove(
@@ -316,7 +322,7 @@ jQuery(function ($) {
$("[shape-id-meta]").detach().prependTo(shapeTracingWindowContent);
// add the expand/collapse logic to the shape model
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingWindowContent.find('li:has(ul:has(li))').prepend($(glyph));
// collapse all sub uls
shapeTracingWindowContent.find('ul ul').toggle(false);
@@ -328,7 +334,7 @@ jQuery(function ($) {
shapeTracingTabsShape.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -338,10 +344,14 @@ jQuery(function ($) {
shapeTracingBreadcrumb.text('');
// create collapsible containers
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
shapeTracingMetaContent.find('ul ul').toggle(false);
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
$('#activeTemplate').click(function () {
displayTabTemplate();
});
defaultTab = displayTabShape;
};
@@ -358,7 +368,7 @@ jQuery(function ($) {
shapeTracingTabsModel.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -368,7 +378,7 @@ jQuery(function ($) {
shapeTracingBreadcrumb.text('');
// create collapsible containers
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend(glyph);
shapeTracingMetaContent.find('li:has(ul:has(li))').prepend($(glyph));
shapeTracingMetaContent.find('ul ul').toggle(false);
shapeTracingMetaContent.find('.expando-glyph-container').click(expandCollapseExpando);
@@ -407,7 +417,7 @@ jQuery(function ($) {
});
// open the root node (Model)
openExpando(shapeTracingMetaContent.find('.expando-glyph-container:first'))
shapeTracingMetaContent.find('.expando-glyph-container:first').click();
defaultTab = displayTabModel;
};
@@ -423,7 +433,7 @@ jQuery(function ($) {
shapeTracingTabsPlacement.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -450,7 +460,7 @@ jQuery(function ($) {
shapeTracingTabsTemplate.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -476,7 +486,7 @@ jQuery(function ($) {
shapeTracingTabsHtml.addClass('selected');
// remove old content
shapeTracingMetaContent.empty();
shapeTracingMetaContent.children().remove();
// render the template
if (currentShape && shapeTracingMetadataHost[currentShape]) {
@@ -507,7 +517,7 @@ jQuery(function ($) {
// hooks the click event on expandos
var expandCollapseExpando = function () {
var _this = $(this);
if (_this.hasClass("closed") || _this.hasClass("closing")) {
if (_this.hasClass("closed")) {
openExpando(_this);
}
else {

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using ClaySharp;
using ClaySharp.Behaviors;
@@ -11,25 +10,22 @@ using Orchard.ContentManagement;
using Orchard.DisplayManagement;
namespace Orchard.DesignerTools.Services {
public class ObjectDumper {
private const int MaxStringLength = 60;
private readonly Stack<object> _parents = new Stack<object>();
private readonly Stack<XElement> _currents = new Stack<XElement>();
private readonly int _levels;
private readonly Dictionary<int, XElement> _local;
private readonly Dictionary<int, XElement> _global;
private readonly XDocument _xdoc;
private XElement _current;
// object/key/dump
public ObjectDumper(int levels, Dictionary<int, XElement> local, Dictionary<int, XElement> global) {
public ObjectDumper(int levels)
{
_levels = levels;
_local = local;
_global = global;
_xdoc = new XDocument();
_xdoc.Add(_current = new XElement("ul"));
}
@@ -40,6 +36,7 @@ namespace Orchard.DesignerTools.Services {
}
_parents.Push(o);
// starts a new container
EnterNode("li");
@@ -51,20 +48,11 @@ namespace Orchard.DesignerTools.Services {
DumpValue(o, name);
}
else {
int hashCode = RuntimeHelpers.GetHashCode(o);
// if the object has already been processed, return a named ref to it
if (_global.ContainsKey(hashCode)) {
_current.Add(
new XElement("h1", new XText(name)),
new XElement("span", FormatType(o)),
new XElement("a", new XAttribute("href", hashCode.ToString()))
);
}
else {
_global.Add(hashCode, _current);
_local.Add(hashCode, _current);
DumpObject(o, name);
if (_parents.Count >= _levels) {
return _current;
}
DumpObject(o, name);
}
}
finally {
@@ -87,29 +75,31 @@ namespace Orchard.DesignerTools.Services {
_current.Add(
new XElement("h1", new XText(name)),
new XElement("span", FormatType(o))
);
);
EnterNode("ul");
if (_parents.Count >= _levels) {
return;
}
try {
if (o is IDictionary) {
DumpDictionary((IDictionary) o);
}
else if (o is IShape) {
DumpShape((IShape) o);
if (o is IDictionary) {
DumpDictionary((IDictionary)o);
}
else if (o is IShape) {
DumpShape((IShape)o);
// a shape can also be IEnumerable
if (o is IEnumerable) {
// a shape can also be IEnumerable
if (o is IEnumerable) {
DumpEnumerable((IEnumerable) o);
}
}
else if (o is IEnumerable) {
DumpEnumerable((IEnumerable) o);
}
else {
DumpMembers(o);
}
}
else if (o is IEnumerable)
{
DumpEnumerable((IEnumerable)o);
}
else {
DumpMembers(o);
finally {
RestoreCurrentNode();
}
}
@@ -124,55 +114,46 @@ namespace Orchard.DesignerTools.Services {
return;
}
EnterNode("ul");
try{
foreach (var member in members) {
if (o is ContentItem && member.Name == "ContentManager"
|| o is Delegate) {
continue;
}
SafeCall(() => DumpMember(o, member));
foreach (var member in members) {
if (o is ContentItem && member.Name == "ContentManager"
|| o is Delegate) {
continue;
}
SafeCall(() => DumpMember(o, member));
}
// process ContentItem.Parts specifically
foreach (var member in members) {
if (o is ContentItem && member.Name == "Parts") {
foreach (var part in ((ContentItem) o).Parts) {
SafeCall(() => Dump(part, part.PartDefinition.Name));
// process ContentItem.Parts specifically
foreach (var member in members) {
if (o is ContentItem && member.Name == "Parts") {
foreach (var part in ((ContentItem) o).Parts) {
// ignore contentparts like ContentPart<ContentItemVersionRecord>
if(part.GetType().IsGenericType) {
continue;
}
}
}
foreach (var member in members) {
// process ContentPart.Fields specifically
if (o is ContentPart && member.Name == "Fields") {
foreach (var field in ((ContentPart) o).Fields) {
SafeCall(() => Dump(field, field.Name));
}
SafeCall(() => Dump(part, part.PartDefinition.Name));
}
}
}
finally {
RestoreCurrentNode();
foreach (var member in members) {
// process ContentPart.Fields specifically
if (o is ContentPart && member.Name == "Fields") {
foreach (var field in ((ContentPart) o).Fields) {
SafeCall(() => Dump(field, field.Name));
}
}
}
}
private void DumpEnumerable(IEnumerable enumerable) {
if(!enumerable.GetEnumerator().MoveNext()) {
if (!enumerable.GetEnumerator().MoveNext()) {
return;
}
EnterNode("ul");
try {
int i = 0;
foreach (var child in enumerable) {
Dump(child, string.Format("[{0}]", i++));
}
}
finally {
RestoreCurrentNode();
int i = 0;
foreach (var child in enumerable) {
Dump(child, string.Format("[{0}]", i++));
}
}
@@ -181,21 +162,14 @@ namespace Orchard.DesignerTools.Services {
return;
}
EnterNode("ul");
try {
foreach (var key in dictionary.Keys) {
Dump(dictionary[key], string.Format("[\"{0}\"]", key));
}
}
finally {
RestoreCurrentNode();
foreach (var key in dictionary.Keys) {
Dump(dictionary[key], string.Format("[\"{0}\"]", key));
}
}
private void DumpShape(IShape shape) {
var b = ((IClayBehaviorProvider)(dynamic)shape).Behavior as ClayBehaviorCollection;
var b = ((IClayBehaviorProvider) (dynamic) shape).Behavior as ClayBehaviorCollection;
if (b == null)
return;
@@ -216,19 +190,12 @@ namespace Orchard.DesignerTools.Services {
return;
}
EnterNode("ul");
try {
foreach (var key in props.Keys) {
// ignore private members (added dynmically by the shape wrapper)
if (key.ToString().StartsWith("_")) {
continue;
}
Dump(props[key], key.ToString());
foreach (var key in props.Keys) {
// ignore private members (added dynmically by the shape wrapper)
if (key.ToString().StartsWith("_")) {
continue;
}
}
finally {
RestoreCurrentNode();
Dump(props[key], key.ToString());
}
}
@@ -305,9 +272,10 @@ namespace Orchard.DesignerTools.Services {
_current = _currents.Pop();
}
private void EnterNode(string tag) {
private XElement EnterNode(string tag) {
SaveCurrentNode();
_current.Add(_current = new XElement(tag));
return _current;
}
}
}

View File

@@ -1,8 +1,7 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Runtime.CompilerServices;
using System.Xml.Linq;
using Orchard.DisplayManagement.Descriptors;
using Orchard.DisplayManagement.Implementation;
@@ -23,7 +22,6 @@ namespace Orchard.DesignerTools.Services {
private readonly IWebSiteFolder _webSiteFolder;
private readonly IAuthorizer _authorizer;
private int _shapeId;
private readonly Dictionary<int, XElement> _dumped = new Dictionary<int, XElement>(1000);
public ShapeTracingFactory(
WorkContext workContext,
@@ -76,10 +74,12 @@ namespace Orchard.DesignerTools.Services {
}
shapeMetadata.Wrappers.Add("ShapeTracingWrapper");
shapeMetadata.OnDisplaying(OnDisplaying);
}
}
public void Displaying(ShapeDisplayingContext context) {}
public void Displaying(ShapeDisplayingContext context) {
public void OnDisplaying(ShapeDisplayingContext context) {
if (!IsActivable()) {
return;
}
@@ -96,24 +96,18 @@ namespace Orchard.DesignerTools.Services {
var descriptor = shapeTable.Descriptors[shapeMetadata.Type];
// dump the Shape's content
var local = new Dictionary<int, XElement>();
new ObjectDumper(6, local, _dumped).Dump(context.Shape, "Model");
context.Shape.Reference = RuntimeHelpers.GetHashCode(context.Shape);
var dump = new ObjectDumper(6).Dump(context.Shape, "Model");
var sb = new StringBuilder();
context.Shape.LocalReferences = new Dictionary<int, string>();
foreach (var key in local.Keys) {
sb.Clear();
ConvertToJSon(local[key], sb);
((Dictionary<int, string>) context.Shape.LocalReferences)[key] = sb.ToString();
}
ConvertToJSon(dump, sb);
shape._Dump = sb.ToString();
shape.Template = null;
shape.OriginalTemplate = descriptor.BindingSource;
foreach (var extension in new[] { ".cshtml", ".aspx" }) {
foreach (var alternate in shapeMetadata.Alternates.Reverse()) {
var alternateFilename = currentTheme.Location + "/" + currentTheme.Id + "/Views/" + alternate.Replace("__", "-").Replace("_", ".") + extension;
foreach (var alternate in shapeMetadata.Alternates.Reverse().Concat(new [] {shapeMetadata.Type}) ) {
var alternateFilename = FormatShapeFilename(alternate, shapeMetadata.Type, shapeMetadata.DisplayType, currentTheme.Location + "/" + currentTheme.Id, extension);
if (_webSiteFolder.FileExists(alternateFilename)) {
shape.Template = alternateFilename;
}
@@ -158,47 +152,59 @@ namespace Orchard.DesignerTools.Services {
public void Displayed(ShapeDisplayedContext context) {
}
private static void ConvertToJSon(XElement x, StringBuilder sb) {
public static void ConvertToJSon(XElement x, StringBuilder sb) {
if(x == null) {
return;
}
switch (x.Name.ToString()) {
case "ul" :
var first = true;
foreach(var li in x.Elements()) {
if (!first) sb.Append(",");
ConvertToJSon(li, sb);
sb.Append(",");
first = false;
}
break;
case "li":
var name = x.Element("h1").Value;
var value = x.Element("span").Value;
sb.AppendFormat("name: \"{0}\", ", FormatJsonValue(name));
sb.AppendFormat("value: \"{0}\"", FormatJsonValue(value));
var a = x.Element("a");
if (a != null) {
sb.AppendFormat(", children: shapeTracingMetadataHost.references[{0}]", a.Attribute("href").Value);
}
sb.AppendFormat("\"name\": \"{0}\", ", FormatJsonValue(name));
sb.AppendFormat("\"value\": \"{0}\"", FormatJsonValue(value));
var ul = x.Element("ul");
if (ul != null) {
sb.Append(", children: [");
if (ul != null && ul.Descendants().Any()) {
sb.Append(", \"children\": [");
first = true;
foreach (var li in ul.Elements()) {
sb.Append("{ ");
sb.Append(first ? "{ " : ", {");
ConvertToJSon(li, sb);
sb.Append(" },");
sb.Append(" }");
first = false;
}
sb.Append("]");
}
break;
}
}
private static string FormatJsonValue(string value) {
// replace " by \" in json strings
return value.Replace("\"", @"\""");
return value.Replace(@"\", @"\\").Replace("\"", @"\""").Replace("\r\n", @"\n").Replace("\n", @"\n");
}
private static string FormatShapeFilename(string shape, string shapeType, string displayType, string themePrefix, string extension) {
if (!String.IsNullOrWhiteSpace(displayType)) {
if (shape.StartsWith(shapeType + "_" + displayType)) {
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
}
}
return themePrefix + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + extension;
}
}
}

View File

@@ -1,16 +1,22 @@
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.DisplayManagement;
using Orchard.Mvc.Filters;
using Orchard.Security;
using Orchard.UI.Admin;
namespace Orchard.DesignerTools.Services {
public class TemplatesFilter : FilterProvider, IResultFilter {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly WorkContext _workContext;
private readonly IAuthorizer _authorizer;
private readonly dynamic _shapeFactory;
public TemplatesFilter(
IWorkContextAccessor workContextAccessor,
WorkContext workContext,
IAuthorizer authorizer,
IShapeFactory shapeFactory) {
_workContextAccessor = workContextAccessor;
_workContext = workContext;
_authorizer = authorizer;
_shapeFactory = shapeFactory;
}
@@ -19,12 +25,27 @@ namespace Orchard.DesignerTools.Services {
if (!(filterContext.Result is ViewResult))
return;
var ctx = _workContextAccessor.GetContext();
var tail = ctx.Layout.Tail;
if(!IsActivable()) {
return;
}
var tail = _workContext.Layout.Tail;
tail.Add(_shapeFactory.ShapeTracingTemplates());
}
public void OnResultExecuted(ResultExecutedContext filterContext) {
}
private bool IsActivable() {
// activate on front-end only
if (AdminFilter.IsApplied(new RequestContext(_workContext.HttpContext, new RouteData())))
return false;
// if not logged as a site owner, still activate if it's a local request (development machine)
if (!_authorizer.Authorize(StandardPermissions.SiteOwner))
return _workContext.HttpContext.Request.IsLocal;
return true;
}
}
}

View File

@@ -75,7 +75,7 @@ button.create-template, button.create-template:hover, background-image:hover {
clear:both;
display:block;
font-size:10pt;
font-family:Segoe;
font-family:Segoe UI,Trebuchet,Arial,Sans-Serif;;
left: 0px;
bottom: 0px;
position:fixed;
@@ -321,10 +321,14 @@ ul#shape-tracing-tabs {
#shape-tracing-window-content .grid-display div.type, #shape-tracing-window-content .grid-display div.value {
position:absolute;
left:66%;
left:40%;
white-space:nowrap;
}
#shape-tracing-window-content div.model div.type, #shape-tracing-window-content div.model div.value {
left:66%;
}
#shape-tracing-breadcrumb {
background:rgba(236, 241, 242, 1.0);
border-bottom:1px solid rgba(182, 188, 189, 1.0);

View File

@@ -1,8 +1,22 @@
@using Orchard.Utility.Extensions;
@functions {
string FormatShapeFilename(string type, string themeId) {
return "~/Themes/" + themeId + "/Views/" + type.Replace("__", "-").Replace("_", ".") + ".cshtml";
string FormatShapeName(string shape) {
string shapeType = Model.ShapeType;
string displayType = Model.DisplayType;
if(!String.IsNullOrWhiteSpace(displayType)) {
if(shape.StartsWith(shapeType + "_" + displayType)) {
shape = shapeType + shape.Substring(shapeType.Length + displayType.Length + 1) + "_" + displayType;
}
}
return shape.Replace("__", "-").Replace("_", ".");
}
string FormatShapeFilename(string shape, string themeId) {
shape = FormatShapeName(shape);
return "~/Themes/" + themeId + "/Views/" + shape.Replace("__", "-").Replace("_", ".") + ".cshtml";
}
string RemoveBeacons(string htmlContent) {
@@ -20,10 +34,6 @@
<script type="text/javascript">
shapeTracingMetadataHost[@Model.ShapeId] = {};
@foreach (var pair in Model.LocalReferences) {
<text>shapeTracingMetadataHost.references[@pair.Key] = { @(new MvcHtmlString(pair.Value)) };</text>
}
shapeTracingMetadataHost[@Model.ShapeId].shape = {
type: '@Model.ShapeType',
template: '@Model.Template',
@@ -32,10 +42,11 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
position: '@(String.IsNullOrEmpty((string)Model.Position) ? T("n/a").Text : Model.Position.ToString())',
placement: '@(String.IsNullOrEmpty((string)Model.PlacementSource) ? T("n/a").Text : Model.PlacementSource.ToString())',
alternates: [
@foreach (var alternate in Model.Alternates) {
@foreach (var alternate in (new[] { (string)Model.ShapeType }).Concat((List<string>)Model.Alternates))
{
<text>{</text>
<text>filename: '@FormatShapeFilename(alternate, WorkContext.CurrentTheme.Id)',</text>
<text>alternate: '@alternate',</text>
<text>alternate: '@FormatShapeName(alternate)',</text>
<text>template: '@Model.Template',</text>
<text>returnUrl: '@Context.Request.RawUrl'</text>
<text>},</text>
@@ -50,11 +61,11 @@ shapeTracingMetadataHost[@Model.ShapeId].shape = {
],
html: '@RemoveEmptyLines(RemoveBeacons(Display(Model.ChildContent).ToString())).Replace(Environment.NewLine, "\\n")',
templateContent: '@(String.IsNullOrWhiteSpace((string)Model.TemplateContent) ? @T("Content not available as coming from source code.") : @Model.TemplateContent.Replace(Environment.NewLine, "\\n"))',
model: shapeTracingMetadataHost.references[@Model.Reference]
model: { @(new MvcHtmlString((string)@Model.Dump)) }
};
@if(!String.IsNullOrEmpty((string)Model.PlacementSource) && !TempData.ContainsKey((string)Model.PlacementSource)) {
TempData[(string)Model.PlacementSource] = new object();
@if (!String.IsNullOrEmpty((string)Model.PlacementSource) && (WorkContext.HttpContext.Items[(string)Model.PlacementSource] == null)) {
WorkContext.HttpContext.Items[(string)Model.PlacementSource] = new object();
<text>shapeTracingMetadataHost.placement['@Model.PlacementSource.ToString()'] = '@Model.PlacementContent.Replace(Environment.NewLine, "\\n")'; </text>
}

View File

@@ -7,11 +7,11 @@
<div id="shape-tracing-window-tree"></div>
<div id="shape-tracing-window-content">
<ul id="shape-tracing-tabs">
<li id="shape-tracing-tabs-shape" class="selected first">Shape</li>
<li id="shape-tracing-tabs-model" class="middle">Model</li>
<li id="shape-tracing-tabs-placement" class="middle">Placement</li>
<li id="shape-tracing-tabs-template" class="middle">Template</li>
<li id="shape-tracing-tabs-html" class="last">HTML</li>
<li id="shape-tracing-tabs-shape" class="selected first">@T("Shape")</li>
<li id="shape-tracing-tabs-model" class="middle">@T("Model")</li>
<li id="shape-tracing-tabs-placement" class="middle">@T("Placement")</li>
<li id="shape-tracing-tabs-template" class="middle">@T("Template")</li>
<li id="shape-tracing-tabs-html" class="last">@T("HTML")</li>
</ul>
<div id="shape-tracing-breadcrumb"></div>
<div id="shape-tracing-meta-content"></div>
@@ -24,11 +24,13 @@
<script id="shape-tracing-tabs-shape-template" type="text/x-jquery-tmpl">
<div class="shape grid-display">
<ul class="properties">
<li class="sgd-s"><div class="name">Shape</div><div class="value">${shape.type}</div></li>
<li class="sgd-t"><div class="name">Template</div><div class="value"><a href="#">${shape.template}</a></div></li>
<li class="sgd-ot"><div class="name">Original Template</div><div class="value">${shape.originalTemplate}</div></li>
<li class="sgd-d"><div class="name">Display Type</div><div class="value">${shape.displayType}</div></li>
<li class="sgd-a"><div class="name">Alternates (${shape.alternates.length})</div>
<li class="sgd-s"><div class="name">@T("Shape").Text</div><div class="value">${shape.type}</div></li>
<li class="sgd-t"><div class="name">@T("Active Template").Text</div><div class="value"><a id="activeTemplate" href="#">${shape.template}</a></div></li>
{{if shape.template != shape.originalTemplate}}
<li class="sgd-ot"><div class="name">@T("Original Template").Text Template</div><div class="value">${shape.originalTemplate}</div></li>
{{/if}}
<li class="sgd-d"><div class="name">@T("Display Type").Text</div><div class="value">${shape.displayType}</div></li>
<li class="sgd-a"><div class="name">@T("Alternate ({0})", "${shape.alternates.length}").Text</div>
<div class="value">&nbsp;</div>
<ul>
{{each shape.alternates}}
@@ -47,7 +49,7 @@
{{/each}}
</ul>
</li>
<li class="sgd-w"><div class="name">Wrappers (${shape.wrappers.length})</div>
<li class="sgd-w"><div class="name">@T("Wrappers ({0})", "${shape.wrappers.length}")</div>
<div class="value">&nbsp;</div>
<ul>
{{each shape.wrappers}}

View File

@@ -40,7 +40,6 @@
Wrappers: Model.Metadata.Wrappers,
ChildContent: Model.Metadata.ChildContent,
ShapeId: Model.ShapeId,
Reference: Model.Reference,
LocalReferences: Model.LocalReferences
Dump: Model._Dump
));
}

View File

@@ -2,7 +2,7 @@
@using System.Net.Mail;
<fieldset>
<legend>@T("SMTP")</legend>
<legend>@T("Email")</legend>
<div>
<label for="@Html.FieldIdFor(m => m.Address)">@T("Sender email address")</label>
@Html.EditorFor(m => m.Address)

View File

@@ -1,11 +1,11 @@
@model Orchard.Indexing.ViewModels.IndexViewModel
@using Orchard.Indexing.Services;
@{ Layout.Title = T("Search Index Management").ToString(); }
@{ Layout.Title = T("Settings").ToString(); }
@using (Html.BeginForm("update", "admin", FormMethod.Post, new {area = "Orchard.Indexing"})) {
<fieldset>
<legend>@T("Search Index Statistics")</legend>
<legend>@T("Search Index")</legend>
<ol class="decimal">
@if (Model.IndexEntry == null) {

View File

@@ -311,7 +311,7 @@ namespace Lists.Controllers {
// ensure the item can be in that container.
if (!string.IsNullOrEmpty(itemContentType) && item.ContentType != itemContentType) {
Services.TransactionManager.Cancel();
Services.Notifier.Information(T("One or more items could not be moved to '{0}' because it is restricted to containing items of type '{1}'.", _contentManager.GetItemMetadata(targetContainer).DisplayText, itemContentType));
Services.Notifier.Information(T("One or more items could not be moved to '{0}' because it is restricted to containing items of type '{1}'.", _contentManager.GetItemMetadata(targetContainer).DisplayText ?? targetContainer.ContentItem.ContentType, itemContentType));
return true; // todo: transactions
}
@@ -319,7 +319,7 @@ namespace Lists.Controllers {
FixItemPath(item);
}
Services.Notifier.Information(T("Content successfully moved to <a href=\"{0}\">{1}</a>.",
Url.Action("List", new { containerId = targetContainerId }), _contentManager.GetItemMetadata(targetContainer).DisplayText));
Url.Action("List", new { containerId = targetContainerId }), _contentManager.GetItemMetadata(targetContainer).DisplayText ?? targetContainer.ContentItem.ContentType));
return true;
}

View File

@@ -8,14 +8,14 @@
var targetContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
contentItem => new SelectListItem {
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText).ToString(),
Text = T("Move to {0}", contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText ?? contentItem.ContentType).ToString(),
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
Selected = contentItem.Id == targetContainerId
}).ToList();
var sourceContainers = ((IEnumerable<ContentItem>)Model.Containers).Select(
contentItem => new SelectListItem {
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText,
Text = contentItem.ContentManager.GetItemMetadata(contentItem).DisplayText ?? contentItem.ContentType,
Value = contentItem.Id.ToString(System.Globalization.CultureInfo.InvariantCulture),
Selected = contentItem.Id == sourceContainerId
}).ToList();

View File

@@ -31,15 +31,16 @@
</div>
@using (Html.BeginFormAntiForgeryPost()) {
var options = (ContentOptions) Model.Options;
<fieldset class="bulk-actions">
<label for="publishActions">@T("Actions:")</label>
<select id="publishActions" name="Options.BulkAction">
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
@Html.SelectOption((ContentsBulkAction)Model.Options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.None, T("Choose action...").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.PublishNow, T("Publish Now").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.Unpublish, T("Unpublish").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.Remove, T("Delete").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.RemoveFromList, T("Remove from List").ToString())
@Html.SelectOption(options.BulkAction, ContentsBulkAction.MoveToList, T("Move to List...").ToString())
</select>
@Html.DropDownList("TargetContainerId", lists, new { id = "TargetContainerId" })
<button type="submit" name="submit.BulkEdit" value="yes">@T("Apply")</button>

View File

@@ -233,16 +233,8 @@ namespace Orchard.Media.Controllers {
}
}
public ActionResult EditMedia(string name, DateTime lastUpdated, long size, string folderName, string mediaPath) {
var model = new MediaItemEditViewModel();
model.Name = name;
// todo: reimplement
//model.Caption = caption ?? String.Empty;
model.LastUpdated = lastUpdated;
model.Size = size;
model.FolderName = folderName;
model.MediaPath = mediaPath;
model.PublicUrl = _mediaService.GetPublicUrl(Path.Combine(mediaPath, name));
public ActionResult EditMedia(MediaItemEditViewModel model) {
model.PublicUrl = _mediaService.GetPublicUrl(Path.Combine(model.MediaPath, model.Name));
return View(model);
}
@@ -293,9 +285,8 @@ namespace Orchard.Media.Controllers {
mediaPath = viewModel.MediaPath });
}
catch (Exception exception) {
this.Error(exception, T("Editing media file failed: {0}", exception.Message), Logger, Services.Notifier);
return View(viewModel);
this.Error(exception, T("Editing media file failed."), Logger, Services.Notifier);
return EditMedia(viewModel);
}
}
}

View File

@@ -140,7 +140,10 @@ namespace Orchard.Media.Services {
Argument.ThrowIfNullOrEmpty(newFileName, "newFileName");
if (!FileAllowed(newFileName, false)) {
throw new ArgumentException(T("New file name {0} is not allowed", newFileName).ToString());
if (string.IsNullOrEmpty(Path.GetExtension(newFileName))) {
throw new ArgumentException(T("New file name \"{0}\" is not allowed. Please provide a file extension.", newFileName).ToString());
}
throw new ArgumentException(T("New file name \"{0}\" is not allowed.", newFileName).ToString());
}
_storageProvider.RenameFile(_storageProvider.Combine(folderPath, currentFileName), _storageProvider.Combine(folderPath, newFileName));

View File

@@ -1,7 +1,7 @@
@model Orchard.Media.Models.MediaSettingsPartRecord
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("Media")</legend>
<div>
@Html.LabelFor(m => m.UploadAllowedFileTypeWhitelist, T("Upload allowed file types (list of extensions separated by spaces)"))
@Html.TextBoxFor(m => m.UploadAllowedFileTypeWhitelist, new { @class = "textMedium" })

View File

@@ -11,6 +11,7 @@
Layout.Title = T("Modules").ToString();
}
@using (Html.BeginFormAntiForgeryPost(Url.Action("Index", "Admin"))) {
<fieldset class="search-actions">
<input type="text" id="searchText" class="text-box single-line" name="@Html.NameOf(m => m.Options.SearchText)" value="@Model.Options.SearchText" />
@@ -18,6 +19,10 @@
<button type="submit">@T("Search").ToString()</button>
</fieldset>
if (Model.InstallModules) {
<span>@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</span>
}
if (Model.Modules.Count() > 0) {
<ul class="contentItems">
@foreach (ModuleEntry module in Model.Modules.OrderBy(m => m.Descriptor.Name)) {
@@ -31,6 +36,3 @@
@Display(Model.Pager)
}
@if (Model.InstallModules) {
<p id="otherActionsBar">@Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null)</p>
}

View File

@@ -1,24 +1,8 @@
#main .features h2 {
margin-top:0;
}
#main .features h3 {
padding:0 3em 0 0;
}
html.dyn #main ul.features button
{
display:none;
}
#otherActionsBar {
clear: both;
border-top-width: thin;
border-top-style: solid;
border-top-color: #E4E5E6;
margin: 10px 0 0;
padding: 10px 0 0;
}
.pageStatus {
clear: both;
}
#main .features h2 { margin-top:0; }
#main .features h3 { padding:0 3em 0 0; }
html.dyn #main ul.features button { display:none; }
.pageStatus { clear: both; }
.features.detail-view .category > ul {
border:1px solid #EAEAEA;
margin-bottom:2em;
@@ -162,8 +146,7 @@ h2.recentlyInstalledModule {padding:0 0 0 40px;}
.search-actions {
float: right;
height: auto;
margin: 0 0 16px 0;
padding-top: 0;
padding:0 0 0 0;
}
.manage {

View File

@@ -73,22 +73,15 @@ namespace Orchard.Packaging.Services {
.SelectMany(
source => {
var galleryFeedContext = new GalleryFeedContext(new Uri(source.FeedUrl));
IQueryable<PublishedPackage> packages = galleryFeedContext.Packages;
IQueryable<PublishedPackage> packages = includeScreenshots
? galleryFeedContext.Packages.Expand("Screenshots")
: galleryFeedContext.Packages;
if (query != null) {
packages = query(packages);
}
return packages.ToList().Select(
p => {
PublishedScreenshot firstScreenshot = includeScreenshots
? galleryFeedContext.Screenshots
.Where(s => s.PublishedPackageId == p.Id && s.PublishedPackageVersion == p.Version)
.ToList()
.FirstOrDefault()
: null;
return CreatePackageEntry(p, firstScreenshot, packagingSource, galleryFeedContext.GetReadStreamUri(p));
});
return packages.ToList().Select(p => CreatePackageEntry(p, packagingSource, galleryFeedContext.GetReadStreamUri(p)));
}
);
}
@@ -116,12 +109,14 @@ namespace Orchard.Packaging.Services {
#endregion
private static PackagingEntry CreatePackageEntry(PublishedPackage package, PublishedScreenshot screenshot, PackagingSource source, Uri downloadUri) {
private static PackagingEntry CreatePackageEntry(PublishedPackage package, PackagingSource source, Uri downloadUri) {
Uri baseUri = new Uri(string.Format("{0}://{1}:{2}/",
downloadUri.Scheme,
downloadUri.Host,
downloadUri.Port));
PublishedScreenshot screenshot = package.Screenshots.FirstOrDefault();
string iconUrl = GetAbsoluteUri(package.IconUrl, baseUri);
string firstScreenshot = screenshot != null ? GetAbsoluteUri(screenshot.ScreenshotUri, baseUri) : string.Empty;

View File

@@ -84,7 +84,7 @@
@if (!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> } else { @T("Unknown").ToString() }
</li>
<li class="rating">&nbsp;&#124;&nbsp;@T("Rating: ")
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", item.Rating, item.RatingsCount)">
<div class="score" style="width:@(15 * (item.Rating))px">&nbsp;</div>
</div>
</li>

View File

@@ -1,7 +1,8 @@
@model Orchard.Packaging.ViewModels.PackagingSourcesViewModel
@{ Layout.Title = T("Settings for Gallery").ToString(); }
@{ Layout.Title = T("Settings").ToString(); }
<h2>@T("Gallery")</h2>
<div class="manage">
@Html.ActionLink(T("Add Feed").Text, "AddSource", new { }, new { @class = "button primaryAction" })
</div>

View File

@@ -88,7 +88,7 @@
@if (!string.IsNullOrEmpty(item.ProjectUrl)) { <a href="@item.ProjectUrl">@item.ProjectUrl</a> } else { @T("Unknown").ToString() }
</li>
<li class="rating">&nbsp;&#124;&nbsp;@T("Rating: ")
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", item.Rating, item.RatingsCount)">
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", item.Rating, item.RatingsCount)">
<div class="score" style="width:@(15 * (item.Rating))px">&nbsp;</div>
</div>
</li>

View File

@@ -65,7 +65,7 @@
@if (!string.IsNullOrEmpty(module.NewVersionToInstall.ProjectUrl)) { <a href="@module.NewVersionToInstall.ProjectUrl">@module.NewVersionToInstall.ProjectUrl</a> } else { @T("Unknown").ToString() }
</li>
<li><div>&nbsp;&#124;&nbsp;@T("Rating: ")
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", module.NewVersionToInstall.Rating, module.NewVersionToInstall.RatingsCount)">
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", module.NewVersionToInstall.Rating, module.NewVersionToInstall.RatingsCount)">
<div class="score" style="width:@(15 * (module.NewVersionToInstall.Rating))px">&nbsp;</div>
</div>
</div>

View File

@@ -70,7 +70,7 @@
@if (!string.IsNullOrEmpty(theme.NewVersionToInstall.ProjectUrl)) { <a href="@theme.NewVersionToInstall.ProjectUrl">@theme.NewVersionToInstall.ProjectUrl</a> } else { @T("Unknown").ToString() }
</li>
<li><div>&nbsp;&#124;&nbsp;@T("Rating: ")
<div class="ratings" style="width:@(15 * 5)px" title="@T("Ratings: {0} ({1})", theme.NewVersionToInstall.Rating, theme.NewVersionToInstall.RatingsCount)">
<div class="ratings" style="width:@(15 * 5)px" title="@T("Rating: {0} out of 5 ({1} total).", theme.NewVersionToInstall.Rating, theme.NewVersionToInstall.RatingsCount)">
<div class="score" style="width:@(15 * (theme.NewVersionToInstall.Rating))px">&nbsp;</div>
</div>
</div>

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Commands;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
using Orchard.Recipes.Models;
using Orchard.Recipes.Services;
namespace Orchard.Recipes.Commands {
public class RecipesCommands : DefaultOrchardCommandHandler {
private readonly IRecipeHarvester _recipeHarvester;
private readonly IRecipeManager _recipeManager;
private readonly IExtensionManager _extensionManager;
public RecipesCommands(IRecipeHarvester recipeHarvester, IRecipeManager recipeManager, IExtensionManager extensionManager) {
_recipeHarvester = recipeHarvester;
_recipeManager = recipeManager;
_extensionManager = extensionManager;
}
[CommandHelp("recipes harvest <extension-id>\r\n\t" + "Display list of available recipes for an extension")]
[CommandName("recipes harvest")]
public void HarvestRecipes(string extensionId) {
ExtensionDescriptor extensionDescriptor = _extensionManager.GetExtension(extensionId);
if (extensionDescriptor == null) {
throw new OrchardException(T("Could not discover recipes because module '{0}' was not found.", extensionId));
}
IEnumerable<Recipe> recipes = _recipeHarvester.HarvestRecipes(extensionId);
if (recipes == null) {
throw new OrchardException(T("No recipes found for extension {0}.", extensionId));
}
Context.Output.WriteLine(T("List of available recipes"));
Context.Output.WriteLine(T("--------------------------"));
Context.Output.WriteLine();
foreach (Recipe recipe in recipes) {
Context.Output.WriteLine(T("Recipe: {0}", recipe.Name));
Context.Output.WriteLine(T(" Version: {0}", recipe.Version));
Context.Output.WriteLine(T(" Tags: {0}", recipe.Tags));
Context.Output.WriteLine(T(" Description: {0}", recipe.Description));
Context.Output.WriteLine(T(" Author: {0}", recipe.Author));
Context.Output.WriteLine(T(" Website: {0}", recipe.WebSite));
}
}
[CommandHelp("recipes execute <extension-id> <recipe-name>\r\n\t" + "Executes a recipe from a module")]
[CommandName("recipes execute")]
public void ExecuteRecipe(string extensionId, string recipeName) {
ExtensionDescriptor extensionDescriptor = _extensionManager.GetExtension(extensionId);
if (extensionDescriptor == null) {
throw new OrchardException(T("Could not discover recipes because module '{0}' was not found.", extensionId));
}
IEnumerable<Recipe> recipes = _recipeHarvester.HarvestRecipes(extensionId);
if (recipes == null) {
throw new OrchardException(T("No recipes found for extension {0}.", extensionId));
}
Recipe recipe = recipes.FirstOrDefault(r => r.Name.Equals(recipeName, StringComparison.OrdinalIgnoreCase));
if (recipe == null) {
throw new OrchardException(T("Invalid recipe name {0}.", recipeName));
}
try {
_recipeManager.Execute(recipe);
Context.Output.WriteLine(T("Recipe scheduled for execution successfully.").Text);
}
catch {
Context.Output.WriteLine(T("Recipe failed to execute.").Text);
}
}
}
}

View File

@@ -51,6 +51,7 @@
<Content Include="web.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Commands\RecipesCommands.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RecipeHandlers\CommandRecipeHandler.cs" />
<Compile Include="RecipeHandlers\FeatureRecipeHandler.cs" />

View File

@@ -2,7 +2,7 @@
@using Orchard.Search.ViewModels;
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("Search")</legend>
<div>
@{var entryIndex = 0;}

View File

@@ -245,7 +245,7 @@ namespace Orchard.Users.Controllers {
_siteService.GetSiteSettings().As<SiteSettingsPart>().SuperUser = editModel.UserName;
}
user.NormalizedUserName = editModel.UserName.ToLower();
user.NormalizedUserName = editModel.UserName.ToUpperInvariant();
}
}

View File

@@ -1,15 +1,24 @@
using Orchard.Data.Migration;
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Data.Migration;
using Orchard.Users.Models;
namespace Orchard.Users {
public class UsersDataMigration : DataMigrationImpl {
public UsersDataMigration(IOrchardServices orchardServices) {
Services = orchardServices;
}
public IOrchardServices Services { get; set; }
public int Create() {
SchemaBuilder.CreateTable("UserPartRecord",
table => table
.ContentPartRecord()
.Column<string>("UserName")
.Column<string>("Email")
.Column<string>("NormalizedUserName")
.Column<string>("NormalizedUserName", c => c.Unique())
.Column<string>("Password")
.Column<string>("PasswordFormat")
.Column<string>("HashAlgorithm")
@@ -32,7 +41,17 @@ namespace Orchard.Users {
.Column<bool>("EnableLostPassword", c => c.WithDefault(false))
);
return 1;
return 2;
}
public int UpdateFrom1() {
IEnumerable<UserPart> users = Services.ContentManager.Query<UserPart, UserPartRecord>().List();
foreach (UserPart user in users) {
user.NormalizedUserName = user.UserName.ToUpperInvariant();
}
return 2;
}
}
}

View File

@@ -49,7 +49,7 @@ namespace Orchard.Users.Services {
user.Record.UserName = createUserParams.Username;
user.Record.Email = createUserParams.Email;
user.Record.NormalizedUserName = createUserParams.Username.ToLower();
user.Record.NormalizedUserName = createUserParams.Username.ToUpperInvariant();
user.Record.HashAlgorithm = "SHA1";
SetPassword(user.Record, createUserParams.Password);
@@ -97,18 +97,24 @@ namespace Orchard.Users.Services {
}
public IUser GetUser(string username) {
var lowerName = username == null ? "" : username.ToLower();
var higherName = username == null ? "" : username.ToUpperInvariant();
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>()
.Where(u => u.NormalizedUserName == higherName).List()
.FirstOrDefault(u => u.UserName.Equals(username, StringComparison.OrdinalIgnoreCase));
}
public IUser ValidateUser(string userNameOrEmail, string password) {
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLower();
var higherName = userNameOrEmail == null ? "" : userNameOrEmail.ToUpperInvariant();
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
if (user == null)
user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.Email == lowerName).List().FirstOrDefault();
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>()
.Where(u =>
u.NormalizedUserName == higherName ||
u.Email == userNameOrEmail)
.List()
.FirstOrDefault(u =>
u.UserName.Equals(userNameOrEmail, StringComparison.OrdinalIgnoreCase) ||
u.Email == userNameOrEmail);
if ( user == null || ValidatePassword(user.As<UserPart>().Record, password) == false )
return null;

View File

@@ -37,13 +37,16 @@ namespace Orchard.Users.Services {
public ILogger Logger { get; set; }
public bool VerifyUserUnicity(string userName, string email) {
string normalizedUserName = userName.ToLower();
string normalizedUserName = userName.ToUpperInvariant();
if (_contentManager.Query<UserPart, UserPartRecord>()
.Where(user =>
user.NormalizedUserName == normalizedUserName ||
user.Email == email)
.List().Any()) {
.List()
.Any(user =>
user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) ||
user.Email == email)) {
return false;
}
@@ -51,13 +54,17 @@ namespace Orchard.Users.Services {
}
public bool VerifyUserUnicity(int id, string userName, string email) {
string normalizedUserName = userName.ToLower();
string normalizedUserName = userName.ToUpperInvariant();
if (_contentManager.Query<UserPart, UserPartRecord>()
.Where(user =>
user.NormalizedUserName == normalizedUserName ||
user.Email == email)
.List().Any(user => user.Id != id)) {
.List()
.Any(user =>
(user.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) ||
user.Email == email) &&
user.Id != id)) {
return false;
}

View File

@@ -1,7 +1,7 @@
@model Orchard.Users.Models.RegistrationSettingsPartRecord
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("Users")</legend>
<div>
@Html.EditorFor(m => m.UsersCanRegister)
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.UsersCanRegister)">@T("Users can create new accounts on the site")</label>

View File

@@ -2,13 +2,13 @@
@using Orchard.Utility.Extensions;
@using Orchard.Warmup.Models;
@{ Layout.Title = T("Settings for Warmup").ToString(); }
@{ Layout.Title = T("Settings").ToString(); }
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset>
<legend>@T("Enter Settings")</legend>
<legend>@T("Warmup")</legend>
<div>
<label for="@Html.FieldIdFor(m => m.Urls)">@T("Urls for which static warmup pages will be generated")</label>
@Html.TextAreaFor(m => m.Urls, new { @class = "textMedium" })

View File

@@ -544,7 +544,7 @@ span.message {
form { margin: 0; padding: 0;}
legend { font-size: 1.231em; font-weight: normal; border:none;}
fieldset { padding:6px 0 0; margin:0 0 1em 0; border: 0px solid #dbdbdb; }
fieldset { padding:6px 0 0; margin:0 0 12px 0; border: 0px solid #dbdbdb; }
label { font-weight:normal; display:block; padding: 0 0 0.3em 0; }
label.forcheckbox { margin:0 0 0 .4em; display:inline; }
@@ -1032,7 +1032,8 @@ html.dyn #submit-pager, html.dyn .apply-bulk-actions-auto { display:none; }
margin:.5em 0;
}
.settings legend {
margin:0 0 -.4em;
margin:0 0 0 0;
font-size:18px;
}
/* Core Contents and Orchard.PublishLater */