mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 02:44:52 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -206,7 +206,7 @@ namespace Orchard.Specs.Bindings {
|
|||||||
[When(@"I fill in")]
|
[When(@"I fill in")]
|
||||||
public void WhenIFillIn(Table table) {
|
public void WhenIFillIn(Table table) {
|
||||||
var inputs = _doc.DocumentNode
|
var inputs = _doc.DocumentNode
|
||||||
.SelectNodes("(//input|//textarea)") ?? Enumerable.Empty<HtmlNode>();
|
.SelectNodes("(//input|//textarea|//select)") ?? Enumerable.Empty<HtmlNode>();
|
||||||
|
|
||||||
foreach (var row in table.Rows) {
|
foreach (var row in table.Rows) {
|
||||||
var r = row;
|
var r = row;
|
||||||
@@ -244,7 +244,19 @@ namespace Orchard.Specs.Bindings {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
input.Attributes.Add("value", row["value"]);
|
if (string.Equals(input.Name, "select", StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
var options = input.ChildNodes;
|
||||||
|
foreach (var option in options) {
|
||||||
|
if (option.GetAttributeValue("value", "") == row["value"])
|
||||||
|
option.Attributes.Add("selected", "selected");
|
||||||
|
else if (option.Attributes.Contains("selected"))
|
||||||
|
option.Attributes.Remove("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
input.Attributes.Add("value", row["value"]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -196,6 +196,11 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>SiteCompilation.feature</DependentUpon>
|
<DependentUpon>SiteCompilation.feature</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Users.feature.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Users.feature</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UsingSpecFlow.feature.cs">
|
<Compile Include="UsingSpecFlow.feature.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
@@ -296,6 +301,10 @@
|
|||||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>Pages.feature.cs</LastGenOutput>
|
<LastGenOutput>Pages.feature.cs</LastGenOutput>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Users.feature">
|
||||||
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Users.feature.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
<None Include="WebHosting.feature">
|
<None Include="WebHosting.feature">
|
||||||
<Generator>SpecFlowSingleFileGenerator</Generator>
|
<Generator>SpecFlowSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>WebHosting.feature.cs</LastGenOutput>
|
<LastGenOutput>WebHosting.feature.cs</LastGenOutput>
|
||||||
|
262
src/Orchard.Specs/Users.feature
Normal file
262
src/Orchard.Specs/Users.feature
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
Feature: Users
|
||||||
|
In order to prevent users module regressions
|
||||||
|
As a site owner
|
||||||
|
I want to create, search and modify user accounts
|
||||||
|
|
||||||
|
@management
|
||||||
|
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"
|
||||||
|
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"
|
||||||
|
When I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User created"
|
||||||
|
When I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
| UserRoles.Roles[0].Granted | true |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User created"
|
||||||
|
And I should see "Adding role Administrator to user user2"
|
||||||
|
When I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user3 |
|
||||||
|
| Email | user3@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
| UserRoles.Roles[0].Granted | true |
|
||||||
|
| UserRoles.Roles[1].Granted | true |
|
||||||
|
| UserRoles.Roles[2].Granted | true |
|
||||||
|
| UserRoles.Roles[3].Granted | true |
|
||||||
|
| UserRoles.Roles[4].Granted | true |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User created"
|
||||||
|
And I should see "Adding role Administrator to user user3"
|
||||||
|
And I should see "Adding role Editor to user user3"
|
||||||
|
And I should see "Adding role Moderator to user user3"
|
||||||
|
And I should see "Adding role Author to user user3"
|
||||||
|
And I should see "Adding role Contributor to user user3"
|
||||||
|
When I follow "Add a new user"
|
||||||
|
And I hit "Save"
|
||||||
|
Then I should see "The UserName field is required."
|
||||||
|
Then I should see "The Email field is required."
|
||||||
|
Then I should see "The Password field is required."
|
||||||
|
Then I should see "The ConfirmPassword field is required."
|
||||||
|
When I go to "admin/users"
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user4 |
|
||||||
|
| Email | user4@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a123456! |
|
||||||
|
And I hit "Save"
|
||||||
|
Then I should see "Password confirmation must match"
|
||||||
|
|
||||||
|
@management
|
||||||
|
Scenario: I can edit an existing user
|
||||||
|
Given I have installed Orchard
|
||||||
|
When I go to "admin/users"
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User created"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | user1 |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
When I follow "Edit"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User information updated"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
And I should see "user2@domain.com"
|
||||||
|
|
||||||
|
@management
|
||||||
|
Scenario: I should not be able to reuse an existing username or email
|
||||||
|
Given I have installed Orchard
|
||||||
|
When I go to "admin/users"
|
||||||
|
# create user1
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
# create user2
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
# filtering on 'user1' to have only one Edit link to follow
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | user1 |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
When I follow "Edit"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
And I hit "Save"
|
||||||
|
Then I should see "User with that username and/or email already exists."
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
And I hit "Save"
|
||||||
|
Then I should see "User with that username and/or email already exists."
|
||||||
|
|
||||||
|
@filtering
|
||||||
|
Scenario: I should not be able to filter users by name
|
||||||
|
Given I have installed Orchard
|
||||||
|
When I go to "admin/users"
|
||||||
|
# create user1
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
# create user2
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | user1 |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should not see "<a[^>]*>admin</a>"
|
||||||
|
And I should not see "<a[^>]*>user2</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | user1@domain.com |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should not see "<a[^>]*>admin</a>"
|
||||||
|
And I should not see "<a[^>]*>user2</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | @domain.com |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
And I should not see "<a[^>]*>admin</a>"
|
||||||
|
|
||||||
|
@filtering
|
||||||
|
Scenario: I should be able to filter users by status
|
||||||
|
Given I have installed Orchard
|
||||||
|
When I go to "admin/users"
|
||||||
|
# create user1
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user1 |
|
||||||
|
| Email | user1@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
# create user2
|
||||||
|
And I follow "Add a new user"
|
||||||
|
And I fill in
|
||||||
|
| name | value |
|
||||||
|
| UserName | user2 |
|
||||||
|
| Email | user2@domain.com |
|
||||||
|
| Password | a12345! |
|
||||||
|
| ConfirmPassword | a12345! |
|
||||||
|
And I hit "Save"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Search | user1 |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
When I follow "Disable"
|
||||||
|
And I am redirected
|
||||||
|
Then I should see "User user1 disabled"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Filter | Pending |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should not see "<a[^>]*>user2</a>"
|
||||||
|
And I should not see "<a[^>]*>admin</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Filter | EmailPending |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should not see "<a[^>]*>user1</a>"
|
||||||
|
And I should not see "<a[^>]*>user2</a>"
|
||||||
|
And I should not see "<a[^>]*>admin</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Filter | Approved |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should not see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
And I should see "<a[^>]*>admin</a>"
|
||||||
|
When I fill in
|
||||||
|
| name | value |
|
||||||
|
| Options.Filter | All |
|
||||||
|
And I hit "Filter"
|
||||||
|
Then I should see "<a[^>]*>user1</a>"
|
||||||
|
And I should see "<a[^>]*>user2</a>"
|
||||||
|
And I should see "<a[^>]*>admin</a>"
|
715
src/Orchard.Specs/Users.feature.cs
generated
Normal file
715
src/Orchard.Specs/Users.feature.cs
generated
Normal file
@@ -0,0 +1,715 @@
|
|||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by SpecFlow (http://www.specflow.org/).
|
||||||
|
// 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
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
#region Designer generated code
|
||||||
|
namespace Orchard.Specs
|
||||||
|
{
|
||||||
|
using TechTalk.SpecFlow;
|
||||||
|
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.5.0.0")]
|
||||||
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[NUnit.Framework.TestFixtureAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("Users")]
|
||||||
|
public partial class UsersFeature
|
||||||
|
{
|
||||||
|
|
||||||
|
private static TechTalk.SpecFlow.ITestRunner testRunner;
|
||||||
|
|
||||||
|
#line 1 "Users.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"), "Users", "In order to prevent users module regressions\nAs a site owner\nI want to create, se" +
|
||||||
|
"arch and modify user accounts", 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("There is only one user by default")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("management")]
|
||||||
|
public virtual void ThereIsOnlyOneUserByDefault()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("There is only one user by default", new string[] {
|
||||||
|
"management"});
|
||||||
|
#line 7
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 8
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 9
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 10
|
||||||
|
testRunner.Then("I should see \"Manage Users\"");
|
||||||
|
#line 11
|
||||||
|
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I can create a new user")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("management")]
|
||||||
|
public virtual void ICanCreateANewUser()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new user", new string[] {
|
||||||
|
"management"});
|
||||||
|
#line 14
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 15
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 16
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 17
|
||||||
|
testRunner.Then("I should see \"Manage Users\"");
|
||||||
|
#line 18
|
||||||
|
testRunner.When("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table1.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table1.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
table1.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table1.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 19
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table1);
|
||||||
|
#line 25
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 26
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 27
|
||||||
|
testRunner.Then("I should see \"User created\"");
|
||||||
|
#line 28
|
||||||
|
testRunner.When("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
table2.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[0].Granted",
|
||||||
|
"true"});
|
||||||
|
#line 29
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table2);
|
||||||
|
#line 36
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 37
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 38
|
||||||
|
testRunner.Then("I should see \"User created\"");
|
||||||
|
#line 39
|
||||||
|
testRunner.And("I should see \"Adding role Administrator to user user2\"");
|
||||||
|
#line 40
|
||||||
|
testRunner.When("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table3 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user3"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user3@domain.com"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[0].Granted",
|
||||||
|
"true"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[1].Granted",
|
||||||
|
"true"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[2].Granted",
|
||||||
|
"true"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[3].Granted",
|
||||||
|
"true"});
|
||||||
|
table3.AddRow(new string[] {
|
||||||
|
"UserRoles.Roles[4].Granted",
|
||||||
|
"true"});
|
||||||
|
#line 41
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table3);
|
||||||
|
#line 52
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 53
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 54
|
||||||
|
testRunner.Then("I should see \"User created\"");
|
||||||
|
#line 55
|
||||||
|
testRunner.And("I should see \"Adding role Administrator to user user3\"");
|
||||||
|
#line 56
|
||||||
|
testRunner.And("I should see \"Adding role Editor to user user3\"");
|
||||||
|
#line 57
|
||||||
|
testRunner.And("I should see \"Adding role Moderator to user user3\"");
|
||||||
|
#line 58
|
||||||
|
testRunner.And("I should see \"Adding role Author to user user3\"");
|
||||||
|
#line 59
|
||||||
|
testRunner.And("I should see \"Adding role Contributor to user user3\"");
|
||||||
|
#line 60
|
||||||
|
testRunner.When("I follow \"Add a new user\"");
|
||||||
|
#line 61
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 62
|
||||||
|
testRunner.Then("I should see \"The UserName field is required.\"");
|
||||||
|
#line 63
|
||||||
|
testRunner.Then("I should see \"The Email field is required.\"");
|
||||||
|
#line 64
|
||||||
|
testRunner.Then("I should see \"The Password field is required.\"");
|
||||||
|
#line 65
|
||||||
|
testRunner.Then("I should see \"The ConfirmPassword field is required.\"");
|
||||||
|
#line 66
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 67
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table4 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table4.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user4"});
|
||||||
|
table4.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user4@domain.com"});
|
||||||
|
table4.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table4.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a123456!"});
|
||||||
|
#line 68
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table4);
|
||||||
|
#line 74
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 75
|
||||||
|
testRunner.Then("I should see \"Password confirmation must match\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I can edit an existing user")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("management")]
|
||||||
|
public virtual void ICanEditAnExistingUser()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can edit an existing user", new string[] {
|
||||||
|
"management"});
|
||||||
|
#line 78
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 79
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 80
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 81
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table5 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table5.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table5.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
table5.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table5.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 82
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table5);
|
||||||
|
#line 88
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 89
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 90
|
||||||
|
testRunner.Then("I should see \"User created\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table6 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table6.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"user1"});
|
||||||
|
#line 91
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table6);
|
||||||
|
#line 94
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 95
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 96
|
||||||
|
testRunner.When("I follow \"Edit\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table7 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table7.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table7.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
#line 97
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table7);
|
||||||
|
#line 101
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 102
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 103
|
||||||
|
testRunner.Then("I should see \"User information updated\"");
|
||||||
|
#line 104
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 105
|
||||||
|
testRunner.And("I should see \"user2@domain.com\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I should not be able to reuse an existing username or email")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("management")]
|
||||||
|
public virtual void IShouldNotBeAbleToReuseAnExistingUsernameOrEmail()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should not be able to reuse an existing username or email", new string[] {
|
||||||
|
"management"});
|
||||||
|
#line 108
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 109
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 110
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 112
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table8 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table8.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table8.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
table8.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table8.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 113
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table8);
|
||||||
|
#line 119
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 120
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 122
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table9 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table9.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table9.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
table9.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table9.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 123
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table9);
|
||||||
|
#line 129
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 130
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 131
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 132
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table10 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table10.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"user1"});
|
||||||
|
#line 134
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table10);
|
||||||
|
#line 137
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 138
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 139
|
||||||
|
testRunner.When("I follow \"Edit\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table11 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table11.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table11.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
#line 140
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table11);
|
||||||
|
#line 144
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 145
|
||||||
|
testRunner.Then("I should see \"User with that username and/or email already exists.\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table12 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table12.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table12.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
#line 146
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table12);
|
||||||
|
#line 150
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 151
|
||||||
|
testRunner.Then("I should see \"User with that username and/or email already exists.\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I should not be able to filter users by name")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("filtering")]
|
||||||
|
public virtual void IShouldNotBeAbleToFilterUsersByName()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should not be able to filter users by name", new string[] {
|
||||||
|
"filtering"});
|
||||||
|
#line 154
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 155
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 156
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 158
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table13 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table13.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table13.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
table13.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table13.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 159
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table13);
|
||||||
|
#line 165
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 166
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 168
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table14 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table14.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table14.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
table14.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table14.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 169
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table14);
|
||||||
|
#line 175
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 176
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 177
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 178
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table15 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table15.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"user1"});
|
||||||
|
#line 179
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table15);
|
||||||
|
#line 182
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 183
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 184
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line 185
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table16.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"user1@domain.com"});
|
||||||
|
#line 186
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table16);
|
||||||
|
#line 189
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 190
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 191
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line 192
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table17 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table17.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"@domain.com"});
|
||||||
|
#line 193
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table17);
|
||||||
|
#line 196
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 197
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 198
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 199
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
[NUnit.Framework.TestAttribute()]
|
||||||
|
[NUnit.Framework.DescriptionAttribute("I should be able to filter users by status")]
|
||||||
|
[NUnit.Framework.CategoryAttribute("filtering")]
|
||||||
|
public virtual void IShouldBeAbleToFilterUsersByStatus()
|
||||||
|
{
|
||||||
|
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I should be able to filter users by status", new string[] {
|
||||||
|
"filtering"});
|
||||||
|
#line 202
|
||||||
|
this.ScenarioSetup(scenarioInfo);
|
||||||
|
#line 203
|
||||||
|
testRunner.Given("I have installed Orchard");
|
||||||
|
#line 204
|
||||||
|
testRunner.When("I go to \"admin/users\"");
|
||||||
|
#line 206
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table18 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table18.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user1"});
|
||||||
|
table18.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user1@domain.com"});
|
||||||
|
table18.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table18.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 207
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table18);
|
||||||
|
#line 213
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 214
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 216
|
||||||
|
testRunner.And("I follow \"Add a new user\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table19 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table19.AddRow(new string[] {
|
||||||
|
"UserName",
|
||||||
|
"user2"});
|
||||||
|
table19.AddRow(new string[] {
|
||||||
|
"Email",
|
||||||
|
"user2@domain.com"});
|
||||||
|
table19.AddRow(new string[] {
|
||||||
|
"Password",
|
||||||
|
"a12345!"});
|
||||||
|
table19.AddRow(new string[] {
|
||||||
|
"ConfirmPassword",
|
||||||
|
"a12345!"});
|
||||||
|
#line 217
|
||||||
|
testRunner.And("I fill in", ((string)(null)), table19);
|
||||||
|
#line 223
|
||||||
|
testRunner.And("I hit \"Save\"");
|
||||||
|
#line 224
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 225
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 226
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table20 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table20.AddRow(new string[] {
|
||||||
|
"Options.Search",
|
||||||
|
"user1"});
|
||||||
|
#line 227
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table20);
|
||||||
|
#line 230
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 231
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 232
|
||||||
|
testRunner.When("I follow \"Disable\"");
|
||||||
|
#line 233
|
||||||
|
testRunner.And("I am redirected");
|
||||||
|
#line 234
|
||||||
|
testRunner.Then("I should see \"User user1 disabled\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table21 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table21.AddRow(new string[] {
|
||||||
|
"Options.Filter",
|
||||||
|
"Pending"});
|
||||||
|
#line 235
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table21);
|
||||||
|
#line 238
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 239
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 240
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 241
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table22 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table22.AddRow(new string[] {
|
||||||
|
"Options.Filter",
|
||||||
|
"EmailPending"});
|
||||||
|
#line 242
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table22);
|
||||||
|
#line 245
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 246
|
||||||
|
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 247
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 248
|
||||||
|
testRunner.And("I should not see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table23 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table23.AddRow(new string[] {
|
||||||
|
"Options.Filter",
|
||||||
|
"Approved"});
|
||||||
|
#line 249
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table23);
|
||||||
|
#line 252
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 253
|
||||||
|
testRunner.Then("I should not see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 254
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 255
|
||||||
|
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
TechTalk.SpecFlow.Table table24 = new TechTalk.SpecFlow.Table(new string[] {
|
||||||
|
"name",
|
||||||
|
"value"});
|
||||||
|
table24.AddRow(new string[] {
|
||||||
|
"Options.Filter",
|
||||||
|
"All"});
|
||||||
|
#line 256
|
||||||
|
testRunner.When("I fill in", ((string)(null)), table24);
|
||||||
|
#line 259
|
||||||
|
testRunner.And("I hit \"Filter\"");
|
||||||
|
#line 260
|
||||||
|
testRunner.Then("I should see \"<a[^>]*>user1</a>\"");
|
||||||
|
#line 261
|
||||||
|
testRunner.And("I should see \"<a[^>]*>user2</a>\"");
|
||||||
|
#line 262
|
||||||
|
testRunner.And("I should see \"<a[^>]*>admin</a>\"");
|
||||||
|
#line hidden
|
||||||
|
testRunner.CollectScenarioErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
@@ -119,14 +119,23 @@ namespace Orchard.Tests.Modules.Indexing {
|
|||||||
[Test]
|
[Test]
|
||||||
public void PropertiesShouldNotBeLost() {
|
public void PropertiesShouldNotBeLost() {
|
||||||
_provider.CreateIndex("default");
|
_provider.CreateIndex("default");
|
||||||
_provider.Store("default", _provider.New(42).Add("prop1", "value1").Store());
|
_provider.Store("default", _provider.New(42)
|
||||||
|
.Add("prop1", "value1").Store()
|
||||||
|
.Add("prop2", 123).Store()
|
||||||
|
.Add("prop3", 123.456).Store()
|
||||||
|
.Add("prop4", new DateTime(2001,1,1,1,1,1,1)).Store()
|
||||||
|
.Add("prop5", true).Store()
|
||||||
|
);
|
||||||
|
|
||||||
var hit = _provider.CreateSearchBuilder("default").Get(42);
|
var hit = _provider.CreateSearchBuilder("default").Get(42);
|
||||||
|
|
||||||
Assert.IsNotNull(hit);
|
Assert.IsNotNull(hit);
|
||||||
Assert.That(hit.ContentItemId, Is.EqualTo(42));
|
Assert.That(hit.ContentItemId, Is.EqualTo(42));
|
||||||
Assert.That(hit.GetString("prop1"), Is.EqualTo("value1"));
|
Assert.That(hit.GetString("prop1"), Is.EqualTo("value1"));
|
||||||
|
Assert.That(hit.GetInt("prop2"), Is.EqualTo(123));
|
||||||
|
Assert.That(hit.GetDouble("prop3"), Is.EqualTo(123.456));
|
||||||
|
Assert.That(hit.GetDateTime("prop4"), Is.EqualTo(new DateTime(2001, 1, 1, 1, 1, 1, 1)));
|
||||||
|
Assert.That(hit.GetBoolean("prop5"), Is.EqualTo(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@@ -177,6 +177,24 @@ namespace Orchard.Tests.Modules.Indexing {
|
|||||||
Assert.That(date[1].GetDateTime("date") < date[2].GetDateTime("date"), Is.True);
|
Assert.That(date[1].GetDateTime("date") < date[2].GetDateTime("date"), Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ShouldSortByNumber() {
|
||||||
|
_provider.CreateIndex("default");
|
||||||
|
_provider.Store("default", _provider.New(1).Add("downloads", 111).Store());
|
||||||
|
_provider.Store("default", _provider.New(2).Add("downloads", 2222).Store());
|
||||||
|
_provider.Store("default", _provider.New(3).Add("downloads", 3).Store());
|
||||||
|
|
||||||
|
var number = _searchBuilder.SortBy("downloads").Search().ToList();
|
||||||
|
Assert.That(number.Count(), Is.EqualTo(3));
|
||||||
|
Assert.That(number[0].GetInt("downloads") > number[1].GetInt("downloads"), Is.True);
|
||||||
|
Assert.That(number[1].GetInt("downloads") > number[2].GetInt("downloads"), Is.True);
|
||||||
|
|
||||||
|
number = _searchBuilder.SortBy("downloads").Ascending().Search().ToList();
|
||||||
|
Assert.That(number.Count(), Is.EqualTo(3));
|
||||||
|
Assert.That(number[0].GetInt("downloads") < number[1].GetInt("downloads"), Is.True);
|
||||||
|
Assert.That(number[1].GetInt("downloads") < number[2].GetInt("downloads"), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldEscapeSpecialChars() {
|
public void ShouldEscapeSpecialChars() {
|
||||||
_provider.CreateIndex("default");
|
_provider.CreateIndex("default");
|
||||||
|
@@ -166,7 +166,6 @@
|
|||||||
<Compile Include="Users\Services\UserServiceTests.cs" />
|
<Compile Include="Users\Services\UserServiceTests.cs" />
|
||||||
<Compile Include="Users\ShellSettingsUtility.cs" />
|
<Compile Include="Users\ShellSettingsUtility.cs" />
|
||||||
<Compile Include="Values.cs" />
|
<Compile Include="Values.cs" />
|
||||||
<Compile Include="Users\Controllers\AdminControllerTests.cs" />
|
|
||||||
<Compile Include="Users\Services\MembershipServiceTests.cs" />
|
<Compile Include="Users\Services\MembershipServiceTests.cs" />
|
||||||
<Compile Include="Widgets\RuleEngine\UrlRuleProviderTest.cs" />
|
<Compile Include="Widgets\RuleEngine\UrlRuleProviderTest.cs" />
|
||||||
<Compile Include="Widgets\Services\WidgetsServiceTest.cs" />
|
<Compile Include="Widgets\Services\WidgetsServiceTest.cs" />
|
||||||
|
@@ -1,170 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Web;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using System.Web.Routing;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Autofac;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using Orchard.Caching;
|
|
||||||
using Orchard.ContentManagement.MetaData;
|
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
|
||||||
using Orchard.ContentManagement.MetaData.Services;
|
|
||||||
using Orchard.Core.Settings.Metadata;
|
|
||||||
using Orchard.Data;
|
|
||||||
using Orchard.DisplayManagement;
|
|
||||||
using Orchard.DisplayManagement.Descriptors;
|
|
||||||
using Orchard.DisplayManagement.Implementation;
|
|
||||||
using Orchard.Environment;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Handlers;
|
|
||||||
using Orchard.ContentManagement.Records;
|
|
||||||
using Orchard.Environment.Extensions;
|
|
||||||
using Orchard.Localization;
|
|
||||||
using Orchard.Messaging.Events;
|
|
||||||
using Orchard.Messaging.Services;
|
|
||||||
using Orchard.Security;
|
|
||||||
using Orchard.Security.Permissions;
|
|
||||||
using Orchard.Security.Providers;
|
|
||||||
using Orchard.Tests.Stubs;
|
|
||||||
using Orchard.UI.Notify;
|
|
||||||
using Orchard.Users.Controllers;
|
|
||||||
using Orchard.Users.Handlers;
|
|
||||||
using Orchard.Users.Models;
|
|
||||||
using Orchard.Users.Services;
|
|
||||||
using Orchard.Users.ViewModels;
|
|
||||||
using Orchard.Settings;
|
|
||||||
using Orchard.Core.Settings.Services;
|
|
||||||
|
|
||||||
namespace Orchard.Tests.Modules.Users.Controllers {
|
|
||||||
[TestFixture]
|
|
||||||
public class AdminControllerTests : DatabaseEnabledTestsBase {
|
|
||||||
private AdminController _controller;
|
|
||||||
private Mock<IAuthorizer> _authorizer;
|
|
||||||
|
|
||||||
public override void Register(ContainerBuilder builder) {
|
|
||||||
builder.RegisterType<AdminController>().SingleInstance();
|
|
||||||
builder.RegisterType<SiteService>().As<ISiteService>();
|
|
||||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
|
||||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>();
|
|
||||||
builder.RegisterType(typeof(SettingsFormatter))
|
|
||||||
.As(typeof(IMapper<XElement, SettingsDictionary>))
|
|
||||||
.As(typeof(IMapper<SettingsDictionary, XElement>));
|
|
||||||
builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>();
|
|
||||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
|
||||||
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>().InstancePerDependency();
|
|
||||||
builder.RegisterType<DefaultMessageManager>().As<IMessageManager>();
|
|
||||||
builder.RegisterInstance(new Mock<IMessageEventHandler>().Object);
|
|
||||||
builder.RegisterType<MembershipService>().As<IMembershipService>();
|
|
||||||
builder.RegisterType<UserService>().As<IUserService>();
|
|
||||||
builder.RegisterType<UserPartHandler>().As<IContentHandler>();
|
|
||||||
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
|
|
||||||
builder.RegisterType<OrchardServices>().As<IOrchardServices>();
|
|
||||||
builder.RegisterType<TransactionManager>().As<ITransactionManager>();
|
|
||||||
builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>();
|
|
||||||
builder.RegisterType<DefaultShapeFactory>().As<IShapeFactory>();
|
|
||||||
builder.RegisterType<StubExtensionManager>().As<IExtensionManager>();
|
|
||||||
builder.RegisterInstance(new Mock<INotifier>().Object);
|
|
||||||
builder.RegisterInstance(new Mock<IContentDisplay>().Object);
|
|
||||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
|
||||||
builder.RegisterType<Signals>().As<ISignals>();
|
|
||||||
builder.RegisterType<DefaultEncryptionService>().As<IEncryptionService>();
|
|
||||||
builder.RegisterInstance(ShellSettingsUtility.CreateEncryptionEnabled());
|
|
||||||
|
|
||||||
_authorizer = new Mock<IAuthorizer>();
|
|
||||||
builder.RegisterInstance(_authorizer.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<Type> DatabaseTypes {
|
|
||||||
get {
|
|
||||||
return new[] { typeof(UserPartRecord),
|
|
||||||
typeof(ContentTypeRecord),
|
|
||||||
typeof(ContentItemRecord),
|
|
||||||
typeof(ContentItemVersionRecord),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Init() {
|
|
||||||
base.Init();
|
|
||||||
|
|
||||||
var manager = _container.Resolve<IContentManager>();
|
|
||||||
|
|
||||||
var userOne = manager.New<UserPart>("User");
|
|
||||||
userOne.Record = new UserPartRecord { UserName = "one" };
|
|
||||||
manager.Create(userOne.ContentItem);
|
|
||||||
|
|
||||||
var userTwo = manager.New<UserPart>("User");
|
|
||||||
userTwo.Record = new UserPartRecord { UserName = "two" };
|
|
||||||
manager.Create(userTwo.ContentItem);
|
|
||||||
|
|
||||||
var userThree = manager.New<UserPart>("User");
|
|
||||||
userThree.Record = new UserPartRecord { UserName = "three" };
|
|
||||||
manager.Create(userThree.ContentItem);
|
|
||||||
|
|
||||||
_controller = _container.Resolve<AdminController>();
|
|
||||||
|
|
||||||
var mockHttpContext = new Mock<HttpContextBase>();
|
|
||||||
_controller.ControllerContext = new ControllerContext(
|
|
||||||
mockHttpContext.Object,
|
|
||||||
new RouteData(
|
|
||||||
new Route("foo", new MvcRouteHandler()),
|
|
||||||
new MvcRouteHandler()),
|
|
||||||
_controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void IndexShouldReturnRowsForUsers() {
|
|
||||||
_authorizer.Setup(x => x.Authorize(It.IsAny<Permission>(), It.IsAny<LocalizedString>())).Returns(true);
|
|
||||||
|
|
||||||
var controller = _container.Resolve<AdminController>();
|
|
||||||
var result = (ViewResult)controller.Index();
|
|
||||||
var model = (UsersIndexViewModel)result.ViewData.Model;
|
|
||||||
|
|
||||||
Assert.That(model.Rows, Is.Not.Null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Ignore("Needs to instead be a specflow test.")]
|
|
||||||
public void CreateShouldAddUserAndRedirect() {
|
|
||||||
_authorizer.Setup(x => x.Authorize(It.IsAny<Permission>(), It.IsAny<LocalizedString>())).Returns(true);
|
|
||||||
|
|
||||||
var controller = _container.Resolve<AdminController>();
|
|
||||||
ActionResult result = null; // controller.CreatePOST(new UserCreateViewModel {
|
|
||||||
// UserName = "four",
|
|
||||||
// Email = "six@example.org",
|
|
||||||
// Password = "five",
|
|
||||||
// ConfirmPassword = "five"
|
|
||||||
//});
|
|
||||||
Assert.That(result, Is.TypeOf<RedirectToRouteResult>());
|
|
||||||
|
|
||||||
var redirect = (RedirectToRouteResult)result;
|
|
||||||
var id = Convert.ToInt32(redirect.RouteValues["id"]);
|
|
||||||
var manager = _container.Resolve<IContentManager>();
|
|
||||||
var user = manager.Get(id).As<IUser>();
|
|
||||||
Assert.That(user.UserName, Is.EqualTo("four"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[Ignore("Needs fixing. Needs to instead be a specflow test.")]
|
|
||||||
public void EditShouldDisplayUserAndStoreChanges() {
|
|
||||||
_authorizer.Setup(x => x.Authorize(It.IsAny<Permission>(), It.IsAny<LocalizedString>())).Returns(true);
|
|
||||||
|
|
||||||
var repository = _container.Resolve<IRepository<UserPartRecord>>();
|
|
||||||
var id = repository.Get(x => x.UserName == "two").Id;
|
|
||||||
var result = (ViewResult)_container.Resolve<AdminController>().Edit(id);
|
|
||||||
var model = (UserEditViewModel)result.ViewData.Model;
|
|
||||||
//Assert.That(model.UserName, Is.EqualTo("two"));
|
|
||||||
|
|
||||||
var controller = _container.Resolve<AdminController>();
|
|
||||||
controller.ValueProvider = Values.From(new {
|
|
||||||
UserName = "bubba",
|
|
||||||
Email = "hotep",
|
|
||||||
});
|
|
||||||
var result2 = controller.EditPOST(id);
|
|
||||||
Assert.That(result2, Is.TypeOf<RedirectToRouteResult>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,7 +15,7 @@ namespace Lucene.Models {
|
|||||||
private string _name;
|
private string _name;
|
||||||
private string _stringValue;
|
private string _stringValue;
|
||||||
private int _intValue;
|
private int _intValue;
|
||||||
private float _floatValue;
|
private double _doubleValue;
|
||||||
private bool _analyze;
|
private bool _analyze;
|
||||||
private bool _store;
|
private bool _store;
|
||||||
private bool _removeTags;
|
private bool _removeTags;
|
||||||
@@ -46,7 +46,7 @@ namespace Lucene.Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IDocumentIndex Add(string name, DateTime value) {
|
public IDocumentIndex Add(string name, DateTime value) {
|
||||||
return Add(name, DateTools.DateToString(value, DateTools.Resolution.SECOND));
|
return Add(name, DateTools.DateToString(value, DateTools.Resolution.MILLISECOND));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDocumentIndex Add(string name, int value) {
|
public IDocumentIndex Add(string name, int value) {
|
||||||
@@ -62,10 +62,10 @@ namespace Lucene.Models {
|
|||||||
return Add(name, value.ToString());
|
return Add(name, value.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDocumentIndex Add(string name, float value) {
|
public IDocumentIndex Add(string name, double value) {
|
||||||
PrepareForIndexing();
|
PrepareForIndexing();
|
||||||
_name = name;
|
_name = name;
|
||||||
_floatValue = value;
|
_doubleValue = value;
|
||||||
_typeCode = TypeCode.Single;
|
_typeCode = TypeCode.Single;
|
||||||
IsDirty = true;
|
IsDirty = true;
|
||||||
return this;
|
return this;
|
||||||
@@ -114,7 +114,7 @@ namespace Lucene.Models {
|
|||||||
case TypeCode.Single:
|
case TypeCode.Single:
|
||||||
Fields.Add(new NumericField(_name,
|
Fields.Add(new NumericField(_name,
|
||||||
_store ? Field.Store.YES : Field.Store.NO,
|
_store ? Field.Store.YES : Field.Store.NO,
|
||||||
true).SetFloatValue(_floatValue));
|
true).SetDoubleValue(_doubleValue));
|
||||||
break;
|
break;
|
||||||
case TypeCode.Empty:
|
case TypeCode.Empty:
|
||||||
break;
|
break;
|
||||||
|
@@ -20,12 +20,12 @@ namespace Lucene.Models {
|
|||||||
|
|
||||||
public int GetInt(string name) {
|
public int GetInt(string name) {
|
||||||
var field = _doc.GetField(name);
|
var field = _doc.GetField(name);
|
||||||
return field == null ? 0 : NumericUtils.PrefixCodedToInt(field.StringValue());
|
return field == null ? 0 : Int32.Parse(field.StringValue(), CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetFloat(string name) {
|
public double GetDouble(string name) {
|
||||||
var field = _doc.GetField(name);
|
var field = _doc.GetField(name);
|
||||||
return field == null ? 0 : float.Parse(field.StringValue(), CultureInfo.InvariantCulture);
|
return field == null ? 0 : double.Parse(field.StringValue(), CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetBoolean(string name) {
|
public bool GetBoolean(string name) {
|
||||||
|
@@ -24,7 +24,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
private readonly IBlogPostService _blogPostService;
|
private readonly IBlogPostService _blogPostService;
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
private readonly ITransactionManager _transactionManager;
|
private readonly ITransactionManager _transactionManager;
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
private readonly ISiteService _siteService;
|
private readonly ISiteService _siteService;
|
||||||
|
|
||||||
public BlogAdminController(
|
public BlogAdminController(
|
||||||
@@ -33,7 +33,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
IBlogPostService blogPostService,
|
IBlogPostService blogPostService,
|
||||||
IContentManager contentManager,
|
IContentManager contentManager,
|
||||||
ITransactionManager transactionManager,
|
ITransactionManager transactionManager,
|
||||||
IBlogSlugConstraint blogSlugConstraint,
|
IBlogPathConstraint blogPathConstraint,
|
||||||
ISiteService siteService,
|
ISiteService siteService,
|
||||||
IShapeFactory shapeFactory) {
|
IShapeFactory shapeFactory) {
|
||||||
Services = services;
|
Services = services;
|
||||||
@@ -41,7 +41,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
_blogPostService = blogPostService;
|
_blogPostService = blogPostService;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_transactionManager = transactionManager;
|
_transactionManager = transactionManager;
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
_siteService = siteService;
|
_siteService = siteService;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Shape = shapeFactory;
|
Shape = shapeFactory;
|
||||||
@@ -81,7 +81,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_contentManager.Publish(blog.ContentItem);
|
_contentManager.Publish(blog.ContentItem);
|
||||||
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug());
|
_blogPathConstraint.AddPath(blog.As<IRoutableAspect>().Path);
|
||||||
|
|
||||||
return Redirect(Url.BlogForAdmin(blog));
|
return Redirect(Url.BlogForAdmin(blog));
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_contentManager.Publish(blog);
|
_contentManager.Publish(blog);
|
||||||
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug());
|
_blogPathConstraint.AddPath(blog.As<IRoutableAspect>().Path);
|
||||||
Services.Notifier.Information(T("Blog information updated"));
|
Services.Notifier.Information(T("Blog information updated"));
|
||||||
|
|
||||||
return Redirect(Url.BlogsForAdmin());
|
return Redirect(Url.BlogsForAdmin());
|
||||||
|
@@ -20,7 +20,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
private readonly IOrchardServices _services;
|
private readonly IOrchardServices _services;
|
||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
private readonly IBlogPostService _blogPostService;
|
private readonly IBlogPostService _blogPostService;
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
private readonly IFeedManager _feedManager;
|
private readonly IFeedManager _feedManager;
|
||||||
private readonly IWorkContextAccessor _workContextAccessor;
|
private readonly IWorkContextAccessor _workContextAccessor;
|
||||||
private readonly IHomePageProvider _routableHomePageProvider;
|
private readonly IHomePageProvider _routableHomePageProvider;
|
||||||
@@ -30,7 +30,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
IBlogService blogService,
|
IBlogService blogService,
|
||||||
IBlogPostService blogPostService,
|
IBlogPostService blogPostService,
|
||||||
IBlogSlugConstraint blogSlugConstraint,
|
IBlogPathConstraint blogPathConstraint,
|
||||||
IFeedManager feedManager,
|
IFeedManager feedManager,
|
||||||
IShapeFactory shapeFactory,
|
IShapeFactory shapeFactory,
|
||||||
IWorkContextAccessor workContextAccessor,
|
IWorkContextAccessor workContextAccessor,
|
||||||
@@ -39,7 +39,7 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
_services = services;
|
_services = services;
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
_blogPostService = blogPostService;
|
_blogPostService = blogPostService;
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
_feedManager = feedManager;
|
_feedManager = feedManager;
|
||||||
_workContextAccessor = workContextAccessor;
|
_workContextAccessor = workContextAccessor;
|
||||||
_siteService = siteService;
|
_siteService = siteService;
|
||||||
@@ -64,13 +64,13 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
return View((object)viewModel);
|
return View((object)viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Item(string blogSlug, PagerParameters pagerParameters) {
|
public ActionResult Item(string blogPath, PagerParameters pagerParameters) {
|
||||||
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||||
var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug);
|
var correctedPath = _blogPathConstraint.FindPath(blogPath);
|
||||||
if (correctedSlug == null)
|
if (correctedPath == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
|
||||||
var blogPart = _blogService.Get(correctedSlug);
|
var blogPart = _blogService.Get(correctedPath);
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
|
||||||
|
@@ -36,12 +36,12 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
//TODO: (erikpo) Should think about moving the slug parameters and get calls and null checks up into a model binder or action filter
|
//TODO: (erikpo) Should think about moving the slug parameters and get calls and null checks up into a model binder or action filter
|
||||||
public ActionResult Item(string blogSlug, string postSlug) {
|
public ActionResult Item(string blogPath, string postSlug) {
|
||||||
if (!_services.Authorizer.Authorize(StandardPermissions.AccessFrontEnd, T("Couldn't view blog post")))
|
if (!_services.Authorizer.Authorize(StandardPermissions.AccessFrontEnd, T("Couldn't view blog post")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
||||||
var blogPart = _blogService.Get(blogSlug);
|
var blogPart = _blogService.Get(blogPath);
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
|
||||||
@@ -55,9 +55,9 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
return View((object)model);
|
return View((object)model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult ListByArchive(string blogSlug, string archiveData) {
|
public ActionResult ListByArchive(string blogPath, string archiveData) {
|
||||||
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
||||||
BlogPart blogPart = _blogService.Get(blogSlug);
|
BlogPart blogPart = _blogService.Get(blogPath);
|
||||||
|
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
@@ -21,10 +21,10 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
|
|
||||||
protected ILogger Logger { get; set; }
|
protected ILogger Logger { get; set; }
|
||||||
|
|
||||||
public ActionResult Rsd(string blogSlug) {
|
public ActionResult Rsd(string blogPath) {
|
||||||
Logger.Debug("RSD requested");
|
Logger.Debug("RSD requested");
|
||||||
|
|
||||||
BlogPart blogPart = _blogService.Get(blogSlug);
|
BlogPart blogPart = _blogService.Get(blogPath);
|
||||||
|
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
using Orchard.Blogs.Models;
|
using System.Linq;
|
||||||
|
using Orchard.Blogs.Models;
|
||||||
|
using Orchard.Blogs.Routing;
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
|
using Orchard.Blogs.ViewModels;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
|
|
||||||
@@ -7,18 +10,22 @@ namespace Orchard.Blogs.Drivers {
|
|||||||
public class BlogArchivesPartDriver : ContentPartDriver<BlogArchivesPart> {
|
public class BlogArchivesPartDriver : ContentPartDriver<BlogArchivesPart> {
|
||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
private readonly IBlogPostService _blogPostService;
|
private readonly IBlogPostService _blogPostService;
|
||||||
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
public BlogArchivesPartDriver(IBlogService blogService, IBlogPostService blogPostService) {
|
public BlogArchivesPartDriver(
|
||||||
|
IBlogService blogService,
|
||||||
|
IBlogPostService blogPostService,
|
||||||
|
IBlogPathConstraint blogPathConstraint) {
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
_blogPostService = blogPostService;
|
_blogPostService = blogPostService;
|
||||||
|
_blogPathConstraint = blogPathConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Display(BlogArchivesPart part, string displayType, dynamic shapeHelper) {
|
protected override DriverResult Display(BlogArchivesPart part, string displayType, dynamic shapeHelper) {
|
||||||
return ContentShape("Parts_Blogs_BlogArchives",
|
return ContentShape("Parts_Blogs_BlogArchives",
|
||||||
() => {
|
() => {
|
||||||
BlogPart blog = null;
|
var path = _blogPathConstraint.FindPath(part.ForBlog);
|
||||||
if (!string.IsNullOrWhiteSpace(part.ForBlog))
|
BlogPart blog = _blogService.Get(path);
|
||||||
blog = _blogService.Get(part.ForBlog);
|
|
||||||
|
|
||||||
if (blog == null)
|
if (blog == null)
|
||||||
return null;
|
return null;
|
||||||
@@ -28,12 +35,21 @@ namespace Orchard.Blogs.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) {
|
protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) {
|
||||||
|
var viewModel = new BlogArchivesViewModel {
|
||||||
|
Path = part.ForBlog,
|
||||||
|
Blogs = _blogService.Get().ToList().OrderBy(b => b.Name)
|
||||||
|
};
|
||||||
|
|
||||||
return ContentShape("Parts_Blogs_BlogArchives_Edit",
|
return ContentShape("Parts_Blogs_BlogArchives_Edit",
|
||||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Blogs.BlogArchives", Model: part, Prefix: Prefix));
|
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Blogs.BlogArchives", Model: viewModel, Prefix: Prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(BlogArchivesPart part, IUpdateModel updater, dynamic shapeHelper) {
|
protected override DriverResult Editor(BlogArchivesPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||||
updater.TryUpdateModel(part, Prefix, null, null);
|
var viewModel = new BlogArchivesViewModel();
|
||||||
|
if (updater.TryUpdateModel(viewModel, Prefix, null, null)) {
|
||||||
|
part.ForBlog = viewModel.Path;
|
||||||
|
}
|
||||||
|
|
||||||
return Editor(part, shapeHelper);
|
return Editor(part, shapeHelper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
|
using Orchard.Blogs.Routing;
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
|
using Orchard.Blogs.ViewModels;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
@@ -10,33 +11,30 @@ namespace Orchard.Blogs.Drivers {
|
|||||||
public class RecentBlogPostsPartDriver : ContentPartDriver<RecentBlogPostsPart> {
|
public class RecentBlogPostsPartDriver : ContentPartDriver<RecentBlogPostsPart> {
|
||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
public RecentBlogPostsPartDriver(IBlogService blogService, IContentManager contentManager) {
|
public RecentBlogPostsPartDriver(
|
||||||
|
IBlogService blogService,
|
||||||
|
IContentManager contentManager,
|
||||||
|
IBlogPathConstraint blogPathConstraint) {
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
_blogPathConstraint = blogPathConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Display(RecentBlogPostsPart part, string displayType, dynamic shapeHelper) {
|
protected override DriverResult Display(RecentBlogPostsPart part, string displayType, dynamic shapeHelper) {
|
||||||
IEnumerable<BlogPostPart> blogPosts;
|
var path = _blogPathConstraint.FindPath(part.ForBlog);
|
||||||
|
BlogPart blog = _blogService.Get(path);
|
||||||
|
|
||||||
BlogPart blog = null;
|
if (blog == null) {
|
||||||
if (!string.IsNullOrWhiteSpace(part.ForBlog))
|
return null;
|
||||||
blog = _blogService.Get(part.ForBlog);
|
}
|
||||||
|
|
||||||
if (blog != null) {
|
var blogPosts =_contentManager.Query(VersionOptions.Published, "BlogPost")
|
||||||
blogPosts = _contentManager.Query(VersionOptions.Published, "BlogPost")
|
.Join<CommonPartRecord>().Where(cr => cr.Container == blog.Record.ContentItemRecord)
|
||||||
.Join<CommonPartRecord>().Where(cr => cr.Container == blog.Record.ContentItemRecord)
|
.OrderByDescending(cr => cr.CreatedUtc)
|
||||||
.OrderByDescending(cr => cr.CreatedUtc)
|
.Slice(0, part.Count)
|
||||||
.Slice(0, part.Count)
|
.Select(ci => ci.As<BlogPostPart>());
|
||||||
.Select(ci => ci.As<BlogPostPart>());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blogPosts = _contentManager.Query(VersionOptions.Published, "BlogPost")
|
|
||||||
.Join<CommonPartRecord>()
|
|
||||||
.OrderByDescending(cr => cr.CreatedUtc)
|
|
||||||
.Slice(0, part.Count)
|
|
||||||
.Select(ci => ci.As<BlogPostPart>());
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = shapeHelper.List();
|
var list = shapeHelper.List();
|
||||||
list.AddRange(blogPosts.Select(bp => _contentManager.BuildDisplay(bp, "Summary")));
|
list.AddRange(blogPosts.Select(bp => _contentManager.BuildDisplay(bp, "Summary")));
|
||||||
@@ -47,12 +45,23 @@ namespace Orchard.Blogs.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(RecentBlogPostsPart part, dynamic shapeHelper) {
|
protected override DriverResult Editor(RecentBlogPostsPart part, dynamic shapeHelper) {
|
||||||
|
var viewModel = new RecentBlogPostsViewModel {
|
||||||
|
Count = part.Count,
|
||||||
|
Path = part.ForBlog,
|
||||||
|
Blogs = _blogService.Get().ToList().OrderBy(b => b.Name)
|
||||||
|
};
|
||||||
|
|
||||||
return ContentShape("Parts_Blogs_RecentBlogPosts_Edit",
|
return ContentShape("Parts_Blogs_RecentBlogPosts_Edit",
|
||||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Blogs.RecentBlogPosts", Model: part, Prefix: Prefix));
|
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Blogs.RecentBlogPosts", Model: viewModel, Prefix: Prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(RecentBlogPostsPart part, IUpdateModel updater, dynamic shapeHelper) {
|
protected override DriverResult Editor(RecentBlogPostsPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||||
updater.TryUpdateModel(part, Prefix, null, null);
|
var viewModel = new RecentBlogPostsViewModel();
|
||||||
|
if (updater.TryUpdateModel(viewModel, Prefix, null, null)) {
|
||||||
|
part.ForBlog = viewModel.Path;
|
||||||
|
part.Count = viewModel.Count;
|
||||||
|
}
|
||||||
|
|
||||||
return Editor(part, shapeHelper);
|
return Editor(part, shapeHelper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ namespace Orchard.Blogs.Extensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string Blog(this UrlHelper urlHelper, BlogPart blogPart) {
|
public static string Blog(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||||
return urlHelper.Action("Item", "Blog", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
|
return urlHelper.Action("Item", "Blog", new { blogPath = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) {
|
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||||
@@ -24,19 +24,19 @@ namespace Orchard.Blogs.Extensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) {
|
public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||||
return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "RemoteBlogPublishing", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }));
|
return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "RemoteBlogPublishing", new { blogPath = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) {
|
public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) {
|
||||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = year.ToString(), area = "Orchard.Blogs" });
|
return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = year.ToString(), area = "Orchard.Blogs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogArchiveMonth(this UrlHelper urlHelper, BlogPart blogPart, int year, int month) {
|
public static string BlogArchiveMonth(this UrlHelper urlHelper, BlogPart blogPart, int year, int month) {
|
||||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
|
return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogArchiveDay(this UrlHelper urlHelper, BlogPart blogPart, int year, int month, int day) {
|
public static string BlogArchiveDay(this UrlHelper urlHelper, BlogPart blogPart, int year, int month, int day) {
|
||||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs" });
|
return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) {
|
public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) {
|
||||||
@@ -60,7 +60,7 @@ namespace Orchard.Blogs.Extensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||||
return urlHelper.Action("Item", "BlogPost", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postSlug = blogPostPart.As<IRoutableAspect>().GetEffectiveSlug(), area = "Orchard.Blogs" });
|
return urlHelper.Action("Item", "BlogPost", new { blogPath = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postSlug = blogPostPart.As<IRoutableAspect>().GetEffectiveSlug(), area = "Orchard.Blogs" });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
|
||||||
|
@@ -16,22 +16,22 @@ namespace Orchard.Blogs.Handlers {
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class BlogPartHandler : ContentHandler {
|
public class BlogPartHandler : ContentHandler {
|
||||||
private readonly IWorkContextAccessor _workContextAccessor;
|
private readonly IWorkContextAccessor _workContextAccessor;
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
private readonly IHomePageProvider _routableHomePageProvider;
|
private readonly IHomePageProvider _routableHomePageProvider;
|
||||||
|
|
||||||
public BlogPartHandler(IRepository<BlogPartRecord> repository, IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders, IBlogSlugConstraint blogSlugConstraint) {
|
public BlogPartHandler(IRepository<BlogPartRecord> repository, IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders, IBlogPathConstraint blogPathConstraint) {
|
||||||
_workContextAccessor = workContextAccessor;
|
_workContextAccessor = workContextAccessor;
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
|
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
|
||||||
Filters.Add(StorageFilter.For(repository));
|
Filters.Add(StorageFilter.For(repository));
|
||||||
|
|
||||||
Action<PublishContentContext, RoutePart> publishedHandler = (context, route) => {
|
Action<PublishContentContext, RoutePart> publishedHandler = (context, route) => {
|
||||||
if (route.Is<BlogPart>()) {
|
if (route.Is<BlogPart>()) {
|
||||||
if (route.ContentItem.Id != 0 && route.PromoteToHomePage)
|
if (route.ContentItem.Id != 0 && route.PromoteToHomePage)
|
||||||
_blogSlugConstraint.AddSlug("");
|
_blogPathConstraint.AddPath("");
|
||||||
}
|
}
|
||||||
else if (route.ContentItem.Id != 0 && route.PromoteToHomePage) {
|
else if (route.ContentItem.Id != 0 && route.PromoteToHomePage) {
|
||||||
_blogSlugConstraint.RemoveSlug("");
|
_blogPathConstraint.RemovePath("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -78,10 +78,10 @@
|
|||||||
<Compile Include="Handlers\BlogPartArchiveHandler.cs" />
|
<Compile Include="Handlers\BlogPartArchiveHandler.cs" />
|
||||||
<Compile Include="Models\BlogPartArchiveRecord.cs" />
|
<Compile Include="Models\BlogPartArchiveRecord.cs" />
|
||||||
<Compile Include="Permissions.cs" />
|
<Compile Include="Permissions.cs" />
|
||||||
<Compile Include="Routing\IBlogSlugConstraint.cs" />
|
<Compile Include="Routing\IBlogPathConstraint.cs" />
|
||||||
<Compile Include="Routing\IsArchiveConstraint.cs" />
|
<Compile Include="Routing\IsArchiveConstraint.cs" />
|
||||||
<Compile Include="Routing\BlogSlugConstraint.cs" />
|
<Compile Include="Routing\BlogPathConstraint.cs" />
|
||||||
<Compile Include="Routing\BlogSlugConstraintUpdator.cs" />
|
<Compile Include="Routing\BlogPathConstraintUpdator.cs" />
|
||||||
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
|
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
|
||||||
<Compile Include="Services\BlogService.cs" />
|
<Compile Include="Services\BlogService.cs" />
|
||||||
<Compile Include="Controllers\BlogController.cs" />
|
<Compile Include="Controllers\BlogController.cs" />
|
||||||
@@ -96,6 +96,8 @@
|
|||||||
<Compile Include="Services\IBlogPostService.cs" />
|
<Compile Include="Services\IBlogPostService.cs" />
|
||||||
<Compile Include="Services\IBlogService.cs" />
|
<Compile Include="Services\IBlogService.cs" />
|
||||||
<Compile Include="Services\XmlRpcHandler.cs" />
|
<Compile Include="Services\XmlRpcHandler.cs" />
|
||||||
|
<Compile Include="ViewModels\BlogArchivesViewModel.cs" />
|
||||||
|
<Compile Include="ViewModels\RecentBlogPostsViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Content\Admin\images\draft.gif" />
|
<Content Include="Content\Admin\images\draft.gif" />
|
||||||
|
@@ -6,10 +6,10 @@ using Orchard.Mvc.Routes;
|
|||||||
|
|
||||||
namespace Orchard.Blogs {
|
namespace Orchard.Blogs {
|
||||||
public class Routes : IRouteProvider {
|
public class Routes : IRouteProvider {
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
public Routes(IBlogSlugConstraint blogSlugConstraint) {
|
public Routes(IBlogPathConstraint blogPathConstraint) {
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
||||||
@@ -175,14 +175,31 @@ namespace Orchard.Blogs {
|
|||||||
},
|
},
|
||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"{blogSlug}/Archive/{*archiveData}",
|
"Archive/{*archiveData}",
|
||||||
|
new RouteValueDictionary {
|
||||||
|
{"blogPath", ""},
|
||||||
|
{"area", "Orchard.Blogs"},
|
||||||
|
{"controller", "BlogPost"},
|
||||||
|
{"action", "ListByArchive"}
|
||||||
|
},
|
||||||
|
new RouteValueDictionary {
|
||||||
|
{"archiveData", new IsArchiveConstraint()}
|
||||||
|
},
|
||||||
|
new RouteValueDictionary {
|
||||||
|
{"area", "Orchard.Blogs"}
|
||||||
|
},
|
||||||
|
new MvcRouteHandler())
|
||||||
|
},
|
||||||
|
new RouteDescriptor {
|
||||||
|
Route = new Route(
|
||||||
|
"{blogPath}/Archive/{*archiveData}",
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "BlogPost"},
|
{"controller", "BlogPost"},
|
||||||
{"action", "ListByArchive"}
|
{"action", "ListByArchive"}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogSlug", _blogSlugConstraint},
|
{"blogPath", _blogPathConstraint},
|
||||||
{"archiveData", new IsArchiveConstraint()}
|
{"archiveData", new IsArchiveConstraint()}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
@@ -193,14 +210,14 @@ namespace Orchard.Blogs {
|
|||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Priority = 11,
|
Priority = 11,
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"{blogSlug}/rsd",
|
"{blogPath}/rsd",
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "RemoteBlogPublishing"},
|
{"controller", "RemoteBlogPublishing"},
|
||||||
{"action", "Rsd"}
|
{"action", "Rsd"}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogSlug", _blogSlugConstraint}
|
{"blogPath", _blogPathConstraint}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"}
|
{"area", "Orchard.Blogs"}
|
||||||
@@ -210,14 +227,14 @@ namespace Orchard.Blogs {
|
|||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Priority = 11,
|
Priority = 11,
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"{blogSlug}/{postSlug}",
|
"{blogPath}/{postSlug}",
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "BlogPost"},
|
{"controller", "BlogPost"},
|
||||||
{"action", "Item"}
|
{"action", "Item"}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogSlug", _blogSlugConstraint}
|
{"blogPath", _blogPathConstraint}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"}
|
{"area", "Orchard.Blogs"}
|
||||||
@@ -227,15 +244,15 @@ namespace Orchard.Blogs {
|
|||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Priority = 11,
|
Priority = 11,
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"{blogSlug}",
|
"{blogPath}",
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "Blog"},
|
{"controller", "Blog"},
|
||||||
{"action", "Item"},
|
{"action", "Item"},
|
||||||
{"blogSlug", ""}
|
{"blogPath", ""}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogSlug", _blogSlugConstraint}
|
{"blogPath", _blogPathConstraint}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"}
|
{"area", "Orchard.Blogs"}
|
||||||
|
@@ -8,46 +8,55 @@ using Orchard.Logging;
|
|||||||
|
|
||||||
namespace Orchard.Blogs.Routing {
|
namespace Orchard.Blogs.Routing {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class BlogSlugConstraint : IBlogSlugConstraint {
|
public class BlogPathConstraint : IBlogPathConstraint {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Singleton object, per Orchard Shell instance. We need to protect concurrent access to the dictionary.
|
/// Singleton object, per Orchard Shell instance. We need to protect concurrent access to the dictionary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _syncLock = new object();
|
private readonly object _syncLock = new object();
|
||||||
private IDictionary<string, string> _slugs = new Dictionary<string, string>();
|
private IDictionary<string, string> _paths = new Dictionary<string, string>();
|
||||||
|
|
||||||
public BlogSlugConstraint() {
|
public BlogPathConstraint() {
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public void SetSlugs(IEnumerable<string> slugs) {
|
public void SetPaths(IEnumerable<string> paths) {
|
||||||
// Make a copy to avoid performing potential lazy computation inside the lock
|
// Make a copy to avoid performing potential lazy computation inside the lock
|
||||||
var slugsArray = slugs.ToArray();
|
var pathArray = paths.ToArray();
|
||||||
|
|
||||||
lock (_syncLock) {
|
lock (_syncLock) {
|
||||||
_slugs = slugsArray.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(value => value, StringComparer.OrdinalIgnoreCase);
|
_paths = pathArray.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(value => value, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Blog slugs: {0}", string.Join(", ", slugsArray));
|
Logger.Debug("Blog paths: {0}", string.Join(", ", pathArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FindSlug(string slug) {
|
public string FindPath(string path) {
|
||||||
lock (_syncLock) {
|
lock (_syncLock) {
|
||||||
string actual;
|
string actual;
|
||||||
return _slugs.TryGetValue(slug, out actual) ? actual : slug;
|
// path can be null for homepage
|
||||||
|
path = path ?? "";
|
||||||
|
|
||||||
|
return _paths.TryGetValue(path, out actual) ? actual : path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSlug(string slug) {
|
public void AddPath(string path) {
|
||||||
lock (_syncLock) {
|
lock (_syncLock) {
|
||||||
_slugs[slug] = slug;
|
// path can be null for homepage
|
||||||
|
path = path ?? "";
|
||||||
|
|
||||||
|
_paths[path] = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSlug(string slug) {
|
public void RemovePath(string path) {
|
||||||
lock (_syncLock) {
|
lock (_syncLock) {
|
||||||
_slugs.Remove(slug);
|
// path can be null for homepage
|
||||||
|
path = path ?? "";
|
||||||
|
|
||||||
|
_paths.Remove(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +69,7 @@ namespace Orchard.Blogs.Routing {
|
|||||||
var parameterValue = Convert.ToString(value);
|
var parameterValue = Convert.ToString(value);
|
||||||
|
|
||||||
lock (_syncLock) {
|
lock (_syncLock) {
|
||||||
return _slugs.ContainsKey(parameterValue);
|
return _paths.ContainsKey(parameterValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -8,12 +8,12 @@ using Orchard.Tasks;
|
|||||||
|
|
||||||
namespace Orchard.Blogs.Routing {
|
namespace Orchard.Blogs.Routing {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class BlogSlugConstraintUpdator : IOrchardShellEvents, IBackgroundTask {
|
public class BlogPathConstraintUpdator : IOrchardShellEvents, IBackgroundTask {
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
|
|
||||||
public BlogSlugConstraintUpdator(IBlogSlugConstraint blogSlugConstraint, IBlogService blogService) {
|
public BlogPathConstraintUpdator(IBlogPathConstraint blogPathConstraint, IBlogService blogService) {
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ namespace Orchard.Blogs.Routing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Refresh() {
|
private void Refresh() {
|
||||||
_blogSlugConstraint.SetSlugs(_blogService.Get().Select(b => b.As<IRoutableAspect>().Path));
|
_blogPathConstraint.SetPaths(_blogService.Get().Select(b => b.As<IRoutableAspect>().Slug));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Web.Routing;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.Routing {
|
||||||
|
public interface IBlogPathConstraint : IRouteConstraint, ISingletonDependency {
|
||||||
|
void SetPaths(IEnumerable<string> paths);
|
||||||
|
string FindPath(string path);
|
||||||
|
void AddPath(string path);
|
||||||
|
void RemovePath(string path);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,11 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Web.Routing;
|
|
||||||
|
|
||||||
namespace Orchard.Blogs.Routing {
|
|
||||||
public interface IBlogSlugConstraint : IRouteConstraint, ISingletonDependency {
|
|
||||||
void SetSlugs(IEnumerable<string> slugs);
|
|
||||||
string FindSlug(string slug);
|
|
||||||
void AddSlug(string slug);
|
|
||||||
void RemoveSlug(string slug);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -29,9 +29,9 @@ namespace Orchard.Blogs.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BlogPostPart Get(BlogPart blogPart, string slug, VersionOptions versionOptions) {
|
public BlogPostPart Get(BlogPart blogPart, string slug, VersionOptions versionOptions) {
|
||||||
var postSlug = blogPart.As<IRoutableAspect>().GetChildPath(slug);
|
var postPath = blogPart.As<IRoutableAspect>().GetChildPath(slug);
|
||||||
return
|
return
|
||||||
_contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Path == postSlug).
|
_contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Path == postPath).
|
||||||
Join<CommonPartRecord>().Where(cr => cr.Container == blogPart.Record.ContentItemRecord).List().
|
Join<CommonPartRecord>().Where(cr => cr.Container == blogPart.Record.ContentItemRecord).List().
|
||||||
SingleOrDefault().As<BlogPostPart>();
|
SingleOrDefault().As<BlogPostPart>();
|
||||||
}
|
}
|
||||||
|
@@ -11,11 +11,11 @@ namespace Orchard.Blogs.Services {
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class BlogService : IBlogService {
|
public class BlogService : IBlogService {
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
private readonly IBlogSlugConstraint _blogSlugConstraint;
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
public BlogService(IContentManager contentManager, IBlogSlugConstraint blogSlugConstraint) {
|
public BlogService(IContentManager contentManager, IBlogPathConstraint blogPathConstraint) {
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_blogSlugConstraint = blogSlugConstraint;
|
_blogPathConstraint = blogPathConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlogPart Get(string path) {
|
public BlogPart Get(string path) {
|
||||||
@@ -39,9 +39,15 @@ namespace Orchard.Blogs.Services {
|
|||||||
.List();
|
.List();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlogPart GetFromSlug(string slug) {
|
||||||
|
return _contentManager.Query<BlogPart, BlogPartRecord>()
|
||||||
|
.Join<RoutePartRecord>().Where(rr => rr.Slug == slug)
|
||||||
|
.List().FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
public void Delete(ContentItem blog) {
|
public void Delete(ContentItem blog) {
|
||||||
_contentManager.Remove(blog);
|
_contentManager.Remove(blog);
|
||||||
_blogSlugConstraint.RemoveSlug(blog.As<IRoutableAspect>().Path);
|
_blogPathConstraint.RemovePath(blog.As<IRoutableAspect>().Path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Blogs.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.ViewModels {
|
||||||
|
public class BlogArchivesViewModel {
|
||||||
|
public string Path { get; set; }
|
||||||
|
public IEnumerable<BlogPart> Blogs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Blogs.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.ViewModels {
|
||||||
|
public class RecentBlogPostsViewModel {
|
||||||
|
public int Count { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
public IEnumerable<BlogPart> Blogs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +1,17 @@
|
|||||||
@model Orchard.Blogs.Models.BlogArchivesPart
|
@model Orchard.Blogs.ViewModels.BlogArchivesViewModel
|
||||||
|
|
||||||
|
@using Orchard.Blogs.Models;
|
||||||
|
@using Orchard.Core.Routable.Models;
|
||||||
|
@using Orchard.ContentManagement;
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div>
|
<div>
|
||||||
@Html.LabelFor(m => m.ForBlog, T("For Blog"))
|
@Html.LabelFor(m => m.Slug, T("For Blog"))
|
||||||
@Html.TextBoxFor(m => m.ForBlog)
|
<select id="@Html.FieldIdFor(m => m.Slug)" name="@Html.FieldNameFor(m => m.Slug)">
|
||||||
<span class="hint">@T("Show the archives for which blog? Note: specify the blog's slug.")</span>
|
@foreach(BlogPart blog in Model.Blogs) {
|
||||||
|
@Html.SelectOption(Model.Slug, blog.As<RoutePart>().Slug, blog.Name)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<span class="hint">@T("Select which blog you want to display the archives for")</span>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
@@ -1,8 +1,18 @@
|
|||||||
@model Orchard.Blogs.Models.RecentBlogPostsPart
|
@model Orchard.Blogs.ViewModels.RecentBlogPostsViewModel
|
||||||
|
|
||||||
|
@using Orchard.Blogs.Models;
|
||||||
|
@using Orchard.Core.Routable.Models;
|
||||||
|
@using Orchard.ContentManagement;
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div>
|
<div>
|
||||||
@Html.LabelFor(m => m.ForBlog, T("For Blog"))
|
@Html.LabelFor(m => m.Path, T("For Blog"))
|
||||||
@Html.TextBoxFor(m => m.ForBlog)
|
<select id="@Html.FieldIdFor(m => m.Path)" name="@Html.FieldNameFor(m => m.Path)">
|
||||||
|
@foreach(BlogPart blog in Model.Blogs) {
|
||||||
|
@Html.SelectOption(Model.Path, blog.As<RoutePart>().Path, blog.Name)
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
<span class="hint">@T("Select which blog you want to display the recent posts for")</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@Html.LabelFor(m => m.Count, T("Count"))
|
@Html.LabelFor(m => m.Count, T("Count"))
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using System.Web.Routing;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Contents.Controllers;
|
||||||
using Orchard.Core.Settings.Models;
|
using Orchard.Core.Settings.Models;
|
||||||
using Orchard.DisplayManagement;
|
using Orchard.DisplayManagement;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
@@ -12,6 +16,7 @@ using Orchard.Users.ViewModels;
|
|||||||
using Orchard.Mvc.Extensions;
|
using Orchard.Mvc.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
|
using Orchard.UI.Navigation;
|
||||||
|
|
||||||
namespace Orchard.Users.Controllers {
|
namespace Orchard.Users.Controllers {
|
||||||
[ValidateInput(false)]
|
[ValidateInput(false)]
|
||||||
@@ -39,24 +44,107 @@ namespace Orchard.Users.Controllers {
|
|||||||
public IOrchardServices Services { get; set; }
|
public IOrchardServices Services { get; set; }
|
||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
public ActionResult Index() {
|
public ActionResult Index(UserIndexOptions options, PagerParameters pagerParameters) {
|
||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list users")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list users")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
|
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||||
|
|
||||||
|
// default options
|
||||||
|
if (options == null)
|
||||||
|
options = new UserIndexOptions();
|
||||||
|
|
||||||
var users = Services.ContentManager
|
var users = Services.ContentManager
|
||||||
.Query<UserPart, UserPartRecord>()
|
.Query<UserPart, UserPartRecord>();
|
||||||
.Where(x => x.UserName != null)
|
|
||||||
.List();
|
switch (options.Filter) {
|
||||||
|
case UsersFilter.Approved:
|
||||||
|
users = users.Where(u => u.RegistrationStatus == UserStatus.Approved);
|
||||||
|
break;
|
||||||
|
case UsersFilter.Pending:
|
||||||
|
users = users.Where(u => u.RegistrationStatus == UserStatus.Pending);
|
||||||
|
break;
|
||||||
|
case UsersFilter.EmailPending:
|
||||||
|
users = users.Where(u => u.EmailStatus == UserStatus.Approved);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!String.IsNullOrWhiteSpace(options.Search)) {
|
||||||
|
users = users.Where(u => u.UserName.Contains(options.Search) || u.Email.Contains(options.Search));
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagerShape = Shape.Pager(pager).TotalItemCount(users.Count());
|
||||||
|
|
||||||
|
switch (options.Order) {
|
||||||
|
case UsersOrder.Name:
|
||||||
|
users = users.OrderBy(u => u.UserName);
|
||||||
|
break;
|
||||||
|
case UsersOrder.Email:
|
||||||
|
users = users.OrderBy(u => u.Email);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = users
|
||||||
|
.Slice(pager.GetStartIndex(), pager.PageSize)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var model = new UsersIndexViewModel {
|
var model = new UsersIndexViewModel {
|
||||||
Rows = users
|
Users = results
|
||||||
.Select(x => new UsersIndexViewModel.Row { UserPart = x })
|
.Select(x => new UserEntry { User = x.Record })
|
||||||
.ToList()
|
.ToList(),
|
||||||
|
Options = options,
|
||||||
|
Pager = pagerShape
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// maintain previous route data when generating page links
|
||||||
|
var routeData = new RouteData();
|
||||||
|
routeData.Values.Add("Options.Filter", options.Filter);
|
||||||
|
routeData.Values.Add("Options.Search", options.Search);
|
||||||
|
routeData.Values.Add("Options.Order", options.Order);
|
||||||
|
|
||||||
|
pagerShape.RouteData(routeData);
|
||||||
|
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[FormValueRequired("submit.BulkEdit")]
|
||||||
|
public ActionResult Index(FormCollection input) {
|
||||||
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
||||||
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
|
var viewModel = new UsersIndexViewModel {Users = new List<UserEntry>(), Options = new UserIndexOptions()};
|
||||||
|
UpdateModel(viewModel);
|
||||||
|
|
||||||
|
var checkedEntries = viewModel.Users.Where(c => c.IsChecked);
|
||||||
|
switch (viewModel.Options.BulkAction) {
|
||||||
|
case UsersBulkAction.None:
|
||||||
|
break;
|
||||||
|
case UsersBulkAction.Approve:
|
||||||
|
foreach (var entry in checkedEntries) {
|
||||||
|
Approve(entry.User.Id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UsersBulkAction.Disable:
|
||||||
|
foreach (var entry in checkedEntries) {
|
||||||
|
Moderate(entry.User.Id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UsersBulkAction.ChallengeEmail:
|
||||||
|
foreach (var entry in checkedEntries) {
|
||||||
|
SendChallengeEmail(entry.User.Id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UsersBulkAction.Delete:
|
||||||
|
foreach (var entry in checkedEntries) {
|
||||||
|
Delete(entry.User.Id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Index(viewModel.Options, new PagerParameters());
|
||||||
|
}
|
||||||
|
|
||||||
public ActionResult Create() {
|
public ActionResult Create() {
|
||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
@@ -109,7 +197,7 @@ namespace Orchard.Users.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Services.Notifier.Information(T("User created"));
|
Services.Notifier.Information(T("User created"));
|
||||||
return RedirectToAction("edit", new { user.Id });
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Edit(int id) {
|
public ActionResult Edit(int id) {
|
||||||
@@ -163,7 +251,7 @@ namespace Orchard.Users.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Services.Notifier.Information(T("User information updated"));
|
Services.Notifier.Information(T("User information updated"));
|
||||||
return RedirectToAction("Edit", new { id });
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Delete(int id) {
|
public ActionResult Delete(int id) {
|
||||||
@@ -181,7 +269,7 @@ namespace Orchard.Users.Controllers {
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Services.ContentManager.Remove(user.ContentItem);
|
Services.ContentManager.Remove(user.ContentItem);
|
||||||
Services.Notifier.Information(T("User deleted"));
|
Services.Notifier.Information(T("User {0} deleted", user.UserName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,13 +280,13 @@ namespace Orchard.Users.Controllers {
|
|||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var user = Services.ContentManager.Get(id);
|
var user = Services.ContentManager.Get<IUser>(id);
|
||||||
|
|
||||||
if ( user != null ) {
|
if ( user != null ) {
|
||||||
_userService.SendChallengeEmail(user.As<UserPart>(), nonce => Url.AbsoluteAction(() => Url.Action("ChallengeEmail", "Account", new {Area = "Orchard.Users", nonce = nonce})));
|
_userService.SendChallengeEmail(user.As<UserPart>(), nonce => Url.AbsoluteAction(() => Url.Action("ChallengeEmail", "Account", new {Area = "Orchard.Users", nonce = nonce})));
|
||||||
|
Services.Notifier.Information(T("Challenge email sent to {0}", user.UserName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.Notifier.Information(T("Challenge email sent"));
|
|
||||||
|
|
||||||
return RedirectToAction("Index");
|
return RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
@@ -207,11 +295,11 @@ namespace Orchard.Users.Controllers {
|
|||||||
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage users")))
|
||||||
return new HttpUnauthorizedResult();
|
return new HttpUnauthorizedResult();
|
||||||
|
|
||||||
var user = Services.ContentManager.Get(id);
|
var user = Services.ContentManager.Get<IUser>(id);
|
||||||
|
|
||||||
if ( user != null ) {
|
if ( user != null ) {
|
||||||
user.As<UserPart>().RegistrationStatus = UserStatus.Approved;
|
user.As<UserPart>().RegistrationStatus = UserStatus.Approved;
|
||||||
Services.Notifier.Information(T("User approved"));
|
Services.Notifier.Information(T("User {0} approved", user.UserName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return RedirectToAction("Index");
|
return RedirectToAction("Index");
|
||||||
|
@@ -4,10 +4,40 @@ using Orchard.Users.Models;
|
|||||||
namespace Orchard.Users.ViewModels {
|
namespace Orchard.Users.ViewModels {
|
||||||
|
|
||||||
public class UsersIndexViewModel {
|
public class UsersIndexViewModel {
|
||||||
public class Row {
|
public IList<UserEntry> Users { get; set; }
|
||||||
public UserPart UserPart { get; set; }
|
public UserIndexOptions Options { get; set; }
|
||||||
}
|
public dynamic Pager { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public IList<Row> Rows { get; set; }
|
public class UserEntry {
|
||||||
|
public UserPartRecord User { get; set; }
|
||||||
|
public bool IsChecked { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserIndexOptions {
|
||||||
|
public string Search { get; set; }
|
||||||
|
public UsersOrder Order { get; set; }
|
||||||
|
public UsersFilter Filter { get; set; }
|
||||||
|
public UsersBulkAction BulkAction { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UsersOrder {
|
||||||
|
Name,
|
||||||
|
Email
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UsersFilter {
|
||||||
|
All,
|
||||||
|
Approved,
|
||||||
|
Pending,
|
||||||
|
EmailPending
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UsersBulkAction {
|
||||||
|
None,
|
||||||
|
Delete,
|
||||||
|
Disable,
|
||||||
|
Approve,
|
||||||
|
ChallengeEmail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +1,101 @@
|
|||||||
@model Orchard.Users.ViewModels.UsersIndexViewModel
|
@model Orchard.Users.ViewModels.UsersIndexViewModel
|
||||||
@using Orchard.Users.Models;
|
@using Orchard.Users.Models;
|
||||||
|
@using Orchard.Users.ViewModels;
|
||||||
|
|
||||||
|
@{
|
||||||
|
var userIndex = 0;
|
||||||
|
|
||||||
|
var pageSizes = new List<int?>() { 10, 50, 100 };
|
||||||
|
var defaultPageSize = WorkContext.CurrentSite.PageSize;
|
||||||
|
if(!pageSizes.Contains(defaultPageSize)) {
|
||||||
|
pageSizes.Add(defaultPageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<h1>@Html.TitleForPage(T("Manage Users").ToString()) </h1>
|
<h1>@Html.TitleForPage(T("Manage Users").ToString()) </h1>
|
||||||
@using (Html.BeginFormAntiForgeryPost()) {
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
@Html.ValidationSummary()
|
@Html.ValidationSummary()
|
||||||
<div class="manage">@Html.ActionLink(T("Add a new user").ToString(), "Create", new { }, new { @class = "button primaryAction" })</div>
|
<div class="manage">@Html.ActionLink(T("Add a new user").ToString(), "Create", new { }, new { @class = "button primaryAction" })</div>
|
||||||
|
|
||||||
|
<fieldset class="bulk-actions">
|
||||||
|
<label for="publishActions">@T("Actions:")</label>
|
||||||
|
<select id="publishActions" name="@Html.NameOf(m => m.Options.BulkAction)">
|
||||||
|
@Html.SelectOption(Model.Options.BulkAction, UsersBulkAction.None, T("Choose action...").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.BulkAction, UsersBulkAction.Approve, T("Approve").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.BulkAction, UsersBulkAction.Disable, T("Disable").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.BulkAction, UsersBulkAction.ChallengeEmail, T("Send challenge E-mail").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.BulkAction, UsersBulkAction.Delete, T("Remove").ToString())
|
||||||
|
</select>
|
||||||
|
<button type="submit" name="submit.BulkEdit" value="@T("Apply")">@T("Apply")</button>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="bulk-actions">
|
||||||
|
@Html.TextBoxFor(m => m.Options.Search, new { @class = "text"})
|
||||||
|
<label for="filterResults">@T("Filter:")</label>
|
||||||
|
<select id="filterResults" name="@Html.NameOf(m => m.Options.Filter)">
|
||||||
|
@Html.SelectOption(Model.Options.Filter, UsersFilter.All, T("All Users").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.Filter, UsersFilter.Approved, T("Approved Users").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.Filter, UsersFilter.Pending, T("Pending Users").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.Filter, UsersFilter.EmailPending, T("Pending Emails").ToString())
|
||||||
|
</select>
|
||||||
|
<label for="filterResults">@T("Sort by:")</label>
|
||||||
|
<select id="filterResults" name="@Html.NameOf(m => m.Options.Order)">
|
||||||
|
@Html.SelectOption(Model.Options.Order, UsersOrder.Name, T("Name").ToString())
|
||||||
|
@Html.SelectOption(Model.Options.Order, UsersOrder.Email, T("Email").ToString())
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="Page" value="1" />
|
||||||
|
<label for="pageSize">@T("Show:")</label>
|
||||||
|
<select id="pageSize" name="PageSize">
|
||||||
|
@Html.SelectOption((int)Model.Pager.PageSize, 0, T("All").ToString())
|
||||||
|
@foreach(int size in pageSizes.OrderBy(p => p)) {
|
||||||
|
@Html.SelectOption((int)Model.Pager.PageSize, size, size.ToString())
|
||||||
|
}
|
||||||
|
<select>
|
||||||
|
<button type="submit" name="submit.Filter" value="@T("Filter")">@T("Filter")</button>
|
||||||
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<table class="items">
|
<table class="items">
|
||||||
<colgroup>
|
|
||||||
<col id="Name" />
|
|
||||||
<col id="Email" />
|
|
||||||
<col id="Edit" />
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th scope="col"> ↓</th>
|
||||||
<th scope="col">@T("Name")</th>
|
<th scope="col">@T("Name")</th>
|
||||||
<th scope="col">@T("Email")</th>
|
<th scope="col">@T("Email")</th>
|
||||||
<th scope="col">@T("") </th>
|
<th scope="col">@T("Actions")</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@foreach (var row in Model.Rows) {
|
@foreach (var entry in Model.Users) {
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@if(row.UserPart.RegistrationStatus == UserStatus.Approved && row.UserPart.EmailStatus == UserStatus.Approved) {
|
<input type="hidden" value="@Model.Users[userIndex].User.Id" name="@Html.NameOf(m => m.Users[userIndex].User.Id)"/>
|
||||||
|
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Users[userIndex].IsChecked)"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@if(entry.User.RegistrationStatus == UserStatus.Approved && entry.User.EmailStatus == UserStatus.Approved) {
|
||||||
<img class="icon" src="@Href("~/Modules/Orchard.Users/Content/Admin/images/online.gif") " alt="@T("Approved") " title="@T("User is approved") " />
|
<img class="icon" src="@Href("~/Modules/Orchard.Users/Content/Admin/images/online.gif") " alt="@T("Approved") " title="@T("User is approved") " />
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<img class="icon" src="@Href("~/Modules/Orchard.Users/Content/Admin/images/offline.gif") " alt="@T("Moderated") " title="@if(row.UserPart.EmailStatus == UserStatus.Approved) { @T("User is moderated") } else { @T("E-mail validation is pending") }" />
|
<img class="icon" src="@Href("~/Modules/Orchard.Users/Content/Admin/images/offline.gif") " alt="@T("Moderated") " title="@if(entry.User.EmailStatus == UserStatus.Approved) { @T("User is moderated") } else { @T("E-mail validation is pending") }" />
|
||||||
}
|
}
|
||||||
@Html.ActionLink(row.UserPart.UserName, "Edit", new { row.UserPart.Id })
|
@Html.ActionLink(entry.User.UserName, "Edit", new { entry.User.Id })
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@row.UserPart.Email
|
@entry.User.Email
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.ActionLink(T("Edit").ToString(), "Edit", new { row.UserPart.Id }) |
|
@Html.ActionLink(T("Edit").ToString(), "Edit", new { entry.User.Id }) |
|
||||||
@Html.ActionLink(T("Remove").ToString(), "Delete", new { row.UserPart.Id }) |
|
@Html.ActionLink(T("Remove").ToString(), "Delete", new { entry.User.Id }) |
|
||||||
@if(row.UserPart.RegistrationStatus == UserStatus.Pending) {
|
@if(entry.User.RegistrationStatus == UserStatus.Pending) {
|
||||||
@Html.ActionLink(T("Approve").ToString(), "Approve", new { row.UserPart.Id })
|
@Html.ActionLink(T("Approve").ToString(), "Approve", new { entry.User.Id })
|
||||||
} else {
|
} else {
|
||||||
@Html.ActionLink(T("Disable").ToString(), "Moderate", new { row.UserPart.Id })
|
@Html.ActionLink(T("Disable").ToString(), "Moderate", new { entry.User.Id })
|
||||||
}
|
}
|
||||||
@if ( row.UserPart.EmailStatus == UserStatus.Pending ) { <text>|</text>
|
@if ( entry.User.EmailStatus == UserStatus.Pending ) { <text>|</text>
|
||||||
@Html.ActionLink(T("Send challenge E-mail").ToString(), "SendChallengeEmail", new { row.UserPart.Id })
|
@Html.ActionLink(T("Send challenge E-mail").ToString(), "SendChallengeEmail", new { entry.User.Id })
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
userIndex++;
|
||||||
|
}
|
||||||
</table>
|
</table>
|
||||||
|
@Display(Model.Pager)
|
||||||
</fieldset>
|
</fieldset>
|
||||||
}
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
@{
|
@{
|
||||||
|
var window = 7; // number of simultaneously displayed pages
|
||||||
var nextText = HasText(Model.NextText) ? Model.NextText : T(">").Text;
|
var nextText = HasText(Model.NextText) ? Model.NextText : T(">").Text;
|
||||||
var previousText = HasText(Model.PreviousText) ? Model.PreviousText : T("<").Text;
|
var previousText = HasText(Model.PreviousText) ? Model.PreviousText : T("<").Text;
|
||||||
|
|
||||||
@@ -18,13 +19,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var totalPageCount = (int) Math.Ceiling((double) Model.TotalItemCount / Model.PageSize);
|
var totalPageCount = (int) Math.Ceiling((double) Model.TotalItemCount / Model.PageSize);
|
||||||
|
var firstPage = Math.Max(1, (int)Model.Page - (window/2));
|
||||||
|
var lastPage = Math.Min(totalPageCount, (int)Model.Page + (window/2));
|
||||||
|
|
||||||
Model.Classes.Add("pager");
|
Model.Classes.Add("pager");
|
||||||
Model.Classes.Add("group");
|
Model.Classes.Add("group");
|
||||||
var tag = Tag(Model, "ul");
|
var tag = Tag(Model, "ul");
|
||||||
|
|
||||||
|
if(Model.RouteData != null) {
|
||||||
|
foreach(var rd in Model.RouteData.Values) {
|
||||||
|
routeData[rd.Key] = rd.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (Model.TotalItemCount > 1) {
|
||||||
|
<span class="page-results">@T("Showing items {0} - {1} of {2}", (Model.Page-1)*(int)Model.PageSize + 1, Model.PageSize == 0 ? Model.TotalItemCount : Math.Min(Model.TotalItemCount, (Model.Page)*(int)Model.PageSize), Model.TotalItemCount)</span>
|
||||||
|
}
|
||||||
|
|
||||||
@if (totalPageCount > 1) {
|
@if (totalPageCount > 1) {
|
||||||
|
routeData["pageSize"] = Model.PageSize;
|
||||||
@tag.StartElement
|
@tag.StartElement
|
||||||
|
// first
|
||||||
|
if(firstPage > 1) {
|
||||||
|
if (routeData.ContainsKey("page")) {
|
||||||
|
routeData.Remove("page");
|
||||||
|
}
|
||||||
|
<li class="page-first">
|
||||||
|
@Html.ActionLink(T("<<").Text, (string)routeData["action"], (string)routeData["controller"], routeData, null)
|
||||||
|
</li>
|
||||||
|
}
|
||||||
// previous page
|
// previous page
|
||||||
if(Model.Page > 1) {
|
if(Model.Page > 1) {
|
||||||
if (Model.Page == 2 && routeData.ContainsKey("page")) {
|
if (Model.Page == 2 && routeData.ContainsKey("page")) {
|
||||||
@@ -38,7 +62,7 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
// page numbers
|
// page numbers
|
||||||
for (var p = 1; p <= totalPageCount; p++) {
|
for (var p = firstPage; p <= lastPage; p++) {
|
||||||
<li class="page-@p">
|
<li class="page-@p">
|
||||||
@if (p == Model.Page) {
|
@if (p == Model.Page) {
|
||||||
<span>@p</span>
|
<span>@p</span>
|
||||||
@@ -61,5 +85,12 @@
|
|||||||
@Html.ActionLink((string)nextText, (string)routeData["action"], (string)routeData["controller"], routeData, null)
|
@Html.ActionLink((string)nextText, (string)routeData["action"], (string)routeData["controller"], routeData, null)
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
// last page
|
||||||
|
if(lastPage < totalPageCount) {
|
||||||
|
routeData["page"] = totalPageCount;
|
||||||
|
<li class="page-last">
|
||||||
|
@Html.ActionLink(T(">>").Text, (string)routeData["action"], (string)routeData["controller"], routeData, null)
|
||||||
|
</li>
|
||||||
|
}
|
||||||
@tag.EndElement
|
@tag.EndElement
|
||||||
}
|
}
|
@@ -10,7 +10,7 @@ namespace Orchard.Indexing {
|
|||||||
IDocumentIndex Add(string name, DateTime value);
|
IDocumentIndex Add(string name, DateTime value);
|
||||||
IDocumentIndex Add(string name, int value);
|
IDocumentIndex Add(string name, int value);
|
||||||
IDocumentIndex Add(string name, bool value);
|
IDocumentIndex Add(string name, bool value);
|
||||||
IDocumentIndex Add(string name, float value);
|
IDocumentIndex Add(string name, double value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores the original value to the index.
|
/// Stores the original value to the index.
|
||||||
|
@@ -5,7 +5,7 @@ namespace Orchard.Indexing {
|
|||||||
float Score { get; }
|
float Score { get; }
|
||||||
|
|
||||||
int GetInt(string name);
|
int GetInt(string name);
|
||||||
float GetFloat(string name);
|
double GetDouble(string name);
|
||||||
bool GetBoolean(string name);
|
bool GetBoolean(string name);
|
||||||
string GetString(string name);
|
string GetString(string name);
|
||||||
DateTime GetDateTime(string name);
|
DateTime GetDateTime(string name);
|
||||||
|
Reference in New Issue
Block a user