Merge branch 'issue/8684' into dev

This commit is contained in:
Benedek Farkas 2024-03-07 19:40:11 +01:00
commit e333952b68
218 changed files with 3318 additions and 2049 deletions

View File

@ -2,15 +2,29 @@ name: Compile
on:
workflow_dispatch:
pull_request:
push:
branches:
- dev
- 1.10.x
jobs:
compile:
name: Compile
defaults:
run:
shell: cmd
shell: pwsh
runs-on: windows-latest
steps:
- name: Test
run: echo Test
- name: Clone repository
uses: actions/checkout@v3.1.0
- name: Restore NuGet packages
run: nuget restore src/Orchard.sln
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.3.1
- name: Compile
run: msbuild Orchard.proj /m /t:Compile /p:MvcBuildViews=true /p:TreatWarningsAsErrors=true -WarnAsError

View File

@ -165,7 +165,7 @@
<NUnit Assemblies="@(TestAssemblies)" ToolPath="@(NUnitPackageToolsFolder)" WorkingDirectory="$(CompileFolder)" OutputXmlFile="$(BuildFolder)\Orchard.Tests.xml" ExcludeCategory="longrunning" />
</Target>
<Target Name="Spec" DependsOnTargets="Package-Stage">
<Target Name="Spec" DependsOnTargets="Compile">
<!-- Running SpecFlow tests -->
<CreateItem Include="$(CompileFolder)\*.Specs.*dll">
<Output TaskParameter="Include" ItemName="SpecAssemblies" />

View File

@ -123,9 +123,6 @@
<Compile Include="Visitors\WhereArgumentsVisitor.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\NH.Linq.snk">
<Link>NH.Linq.snk</Link>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

View File

@ -177,7 +177,7 @@ namespace Orchard.Core.Tests.Common.Providers {
contentManager.UpdateEditor(item.ContentItem, updateModel.Object);
}
class UpdatModelStub : IUpdateModel {
class UpdateModelStub : IUpdateModel {
ModelStateDictionary _modelState = new ModelStateDictionary();
@ -215,11 +215,11 @@ namespace Orchard.Core.Tests.Common.Providers {
var user = contentManager.New<IUser>("User");
_authn.Setup(x => x.GetAuthenticatedUser()).Returns(user);
_authz.Setup(x => x.TryCheckAccess(StandardPermissions.SiteOwner, user, item)).Returns(true);
_authz.Setup(x => x.TryCheckAccess(OwnerEditorPermissions.MayEditContentOwner, user, item)).Returns(true);
item.Owner = user;
var updater = new UpdatModelStub() { Owner = null };
var updater = new UpdateModelStub() { Owner = null };
contentManager.UpdateEditor(item.ContentItem, updater);
}
@ -232,11 +232,11 @@ namespace Orchard.Core.Tests.Common.Providers {
var user = contentManager.New<IUser>("User");
_authn.Setup(x => x.GetAuthenticatedUser()).Returns(user);
_authz.Setup(x => x.TryCheckAccess(StandardPermissions.SiteOwner, user, item)).Returns(true);
_authz.Setup(x => x.TryCheckAccess(OwnerEditorPermissions.MayEditContentOwner, user, item)).Returns(true);
item.Owner = user;
var updater = new UpdatModelStub() { Owner = "" };
var updater = new UpdateModelStub() { Owner = "" };
_container.Resolve<DefaultShapeTableManagerTests.TestShapeProvider>().Discover =
b => b.Describe("Parts_Common_Owner_Edit").From(TestFeature())
@ -255,11 +255,11 @@ namespace Orchard.Core.Tests.Common.Providers {
var user = contentManager.New<IUser>("User");
_authn.Setup(x => x.GetAuthenticatedUser()).Returns(user);
_authz.Setup(x => x.TryCheckAccess(StandardPermissions.SiteOwner, user, item)).Returns(true);
_authz.Setup(x => x.TryCheckAccess(OwnerEditorPermissions.MayEditContentOwner, user, item)).Returns(true);
item.Owner = user;
var updater = new UpdatModelStub() { Owner = "" };
var updater = new UpdateModelStub() { Owner = "" };
_container.Resolve<DefaultShapeTableManagerTests.TestShapeProvider>().Discover =
b => b.Describe("Parts_Common_Owner_Edit").From(TestFeature())
@ -384,7 +384,7 @@ namespace Orchard.Core.Tests.Common.Providers {
_clock.Advance(TimeSpan.FromMinutes(1));
var editUtc = _clock.UtcNow;
var updater = new UpdatModelStub() { Owner = "" };
var updater = new UpdateModelStub() { Owner = "" };
contentManager.UpdateEditor(item.ContentItem, updater);
Assert.That(item.CreatedUtc, Is.EqualTo(createUtc));

View File

@ -3,9 +3,7 @@
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<specFlow>
<!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config -->
</specFlow>
</configuration>

View File

@ -1,15 +1,7 @@
using System;
using NUnit.Framework;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Contents;
using Orchard.Data;
using Orchard.Security;
using Orchard.Security.Permissions;
using System.Linq;
using Orchard.Localization.Services;
using Orchard.Specs.Hosting.Orchard.Web;
using TechTalk.SpecFlow;
using Orchard.Localization.Services;
using System.Linq;
namespace Orchard.Specs.Bindings {
[Binding]
@ -20,7 +12,7 @@ namespace Orchard.Specs.Bindings {
var webApp = Binding<WebAppHosting>();
webApp.Host.Execute(() => {
using ( var environment = MvcApplication.CreateStandaloneEnvironment("Default") ) {
using (var environment = MvcApplication.CreateStandaloneEnvironment("Default")) {
var orchardServices = environment.Resolve<IOrchardServices>();
var cultureManager = environment.Resolve<ICultureManager>();
@ -30,6 +22,11 @@ namespace Orchard.Specs.Bindings {
}
orchardServices.WorkContext.CurrentSite.SiteCulture = cultureName;
// Restarting the shell to reset the cache, because the cache entry storing the list of available
// cultures isn't invalidated by the signal in DefaultCultureManager.ListCultures when running
// inside the test webhost.
MvcApplication.RestartTenant("Default");
}
});
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using Castle.Core.Logging;
using HtmlAgilityPack;
@ -368,6 +369,11 @@ namespace Orchard.Specs.Bindings {
}
}
[When(@"I wait ""(.*)""")]
public void WhenIWait(int waitMilliseconds) {
Thread.Sleep(waitMilliseconds);
}
[Then(@"the status should be (.*) ""(.*)""")]
public void ThenTheStatusShouldBe(int statusCode, string statusDescription) {
Assert.That(Details.StatusCode, Is.EqualTo(statusCode));

View File

@ -171,6 +171,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 1 |
@ -179,6 +180,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 2 |
@ -187,6 +189,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 3 |
@ -195,6 +198,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 4 |
@ -203,6 +207,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 5 |
@ -211,6 +216,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 6 |
@ -219,6 +225,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 7 |
@ -227,6 +234,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 8 |
@ -235,6 +243,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 9 |
@ -243,6 +252,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 10 |
@ -251,6 +261,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 11 |
@ -259,6 +270,7 @@ Scenario: I can create browse blog posts on several pages
And I go to "admin/blogs"
And I follow "My Blog"
And I follow "New Post" where class name has "primaryAction"
And I wait "1000"
And I fill in
| name | value |
| Title.Title | My Post 12 |
@ -269,12 +281,12 @@ Scenario: I can create browse blog posts on several pages
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
And I should see "<h1[^>]*>.*?My Post 12.*?</h1>"
And I should see "<h1[^>]*>.*?My Post 11.*?</h1>"
And I should not see "<h1[^>]*>.*?My Post 10.*?</h1>"
And I should not see "My Post 2"
When I go to "my-blog?page=2"
Then I should see "<h1[^>]*>.*?My Blog.*?</h1>"
And I should see "<h1[^>]*>.*?My Post 1.*?</h1>"
And I should see "<h1[^>]*>.*?My Post 2.*?</h1>"
And I should not see "<h1[^>]*>.*?My Post 3.*?</h1>"
And I should not see "My Post 3"
Scenario: I can create a new blog with a percent sign in the title and it gets stripped out of the slug
Given I have installed Orchard

View File

@ -525,6 +525,8 @@ this.ScenarioSetup(scenarioInfo);
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 173
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 174
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table15 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -532,18 +534,20 @@ this.ScenarioSetup(scenarioInfo);
table15.AddRow(new string[] {
"Title.Title",
"My Post 1"});
#line 174
#line 175
testRunner.And("I fill in", ((string)(null)), table15, "And ");
#line 177
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 178
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 179
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 180
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 181
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 182
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 183
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -551,18 +555,20 @@ this.ScenarioSetup(scenarioInfo);
table16.AddRow(new string[] {
"Title.Title",
"My Post 2"});
#line 182
#line 184
testRunner.And("I fill in", ((string)(null)), table16, "And ");
#line 185
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 186
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 187
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 188
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 189
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 190
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 191
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 192
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table17 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -570,18 +576,20 @@ this.ScenarioSetup(scenarioInfo);
table17.AddRow(new string[] {
"Title.Title",
"My Post 3"});
#line 190
testRunner.And("I fill in", ((string)(null)), table17, "And ");
#line 193
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 194
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 195
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I fill in", ((string)(null)), table17, "And ");
#line 196
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 197
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 198
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 199
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 200
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 201
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table18 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -589,18 +597,20 @@ this.ScenarioSetup(scenarioInfo);
table18.AddRow(new string[] {
"Title.Title",
"My Post 4"});
#line 198
testRunner.And("I fill in", ((string)(null)), table18, "And ");
#line 201
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 202
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 203
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 204
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I fill in", ((string)(null)), table18, "And ");
#line 205
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 206
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 207
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 208
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 209
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 210
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table19 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -608,18 +618,20 @@ this.ScenarioSetup(scenarioInfo);
table19.AddRow(new string[] {
"Title.Title",
"My Post 5"});
#line 206
testRunner.And("I fill in", ((string)(null)), table19, "And ");
#line 209
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 210
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 211
testRunner.And("I fill in", ((string)(null)), table19, "And ");
#line 214
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 215
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 216
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 212
#line 217
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 213
#line 218
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 219
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table20 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -627,18 +639,20 @@ this.ScenarioSetup(scenarioInfo);
table20.AddRow(new string[] {
"Title.Title",
"My Post 6"});
#line 214
testRunner.And("I fill in", ((string)(null)), table20, "And ");
#line 217
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 218
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 219
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 220
testRunner.And("I fill in", ((string)(null)), table20, "And ");
#line 223
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 224
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 225
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 226
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 221
#line 227
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 228
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table21 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -646,18 +660,20 @@ this.ScenarioSetup(scenarioInfo);
table21.AddRow(new string[] {
"Title.Title",
"My Post 7"});
#line 222
testRunner.And("I fill in", ((string)(null)), table21, "And ");
#line 225
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 226
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 227
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 228
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 229
testRunner.And("I fill in", ((string)(null)), table21, "And ");
#line 232
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 233
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 234
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 235
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 236
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 237
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table22 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -665,27 +681,8 @@ this.ScenarioSetup(scenarioInfo);
table22.AddRow(new string[] {
"Title.Title",
"My Post 8"});
#line 230
testRunner.And("I fill in", ((string)(null)), table22, "And ");
#line 233
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 234
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 235
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 236
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 237
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table23 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table23.AddRow(new string[] {
"Title.Title",
"My Post 9"});
#line 238
testRunner.And("I fill in", ((string)(null)), table23, "And ");
testRunner.And("I fill in", ((string)(null)), table22, "And ");
#line 241
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 242
@ -696,6 +693,29 @@ this.ScenarioSetup(scenarioInfo);
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 245
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 246
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table23 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table23.AddRow(new string[] {
"Title.Title",
"My Post 9"});
#line 247
testRunner.And("I fill in", ((string)(null)), table23, "And ");
#line 250
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 251
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 252
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 253
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 254
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 255
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table24 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -703,18 +723,20 @@ this.ScenarioSetup(scenarioInfo);
table24.AddRow(new string[] {
"Title.Title",
"My Post 10"});
#line 246
#line 256
testRunner.And("I fill in", ((string)(null)), table24, "And ");
#line 249
#line 259
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 250
#line 260
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 251
#line 261
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 252
#line 262
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 253
#line 263
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 264
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table25 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -722,18 +744,20 @@ this.ScenarioSetup(scenarioInfo);
table25.AddRow(new string[] {
"Title.Title",
"My Post 11"});
#line 254
#line 265
testRunner.And("I fill in", ((string)(null)), table25, "And ");
#line 257
#line 268
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 258
#line 269
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 259
#line 270
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 260
#line 271
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 261
#line 272
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 273
testRunner.And("I wait \"1000\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table26 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -741,34 +765,34 @@ this.ScenarioSetup(scenarioInfo);
table26.AddRow(new string[] {
"Title.Title",
"My Post 12"});
#line 262
testRunner.And("I fill in", ((string)(null)), table26, "And ");
#line 265
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 266
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 267
testRunner.Then("I should see \"Your Blog Post has been created.\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 268
testRunner.When("I go to \"my-blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 269
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 270
testRunner.And("I should see \"<h1[^>]*>.*?My Post 12.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 271
testRunner.And("I should see \"<h1[^>]*>.*?My Post 11.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 272
testRunner.And("I should not see \"<h1[^>]*>.*?My Post 10.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 273
testRunner.When("I go to \"my-blog?page=2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 274
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 275
testRunner.And("I should see \"<h1[^>]*>.*?My Post 1.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 276
testRunner.And("I should see \"<h1[^>]*>.*?My Post 2.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I fill in", ((string)(null)), table26, "And ");
#line 277
testRunner.And("I should not see \"<h1[^>]*>.*?My Post 3.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 278
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 279
testRunner.Then("I should see \"Your Blog Post has been created.\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 280
testRunner.When("I go to \"my-blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 281
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 282
testRunner.And("I should see \"<h1[^>]*>.*?My Post 12.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 283
testRunner.And("I should see \"<h1[^>]*>.*?My Post 11.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 284
testRunner.And("I should not see \"My Post 2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 285
testRunner.When("I go to \"my-blog?page=2\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 286
testRunner.Then("I should see \"<h1[^>]*>.*?My Blog.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 287
testRunner.And("I should see \"<h1[^>]*>.*?My Post 1.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 288
testRunner.And("I should see \"<h1[^>]*>.*?My Post 2.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 289
testRunner.And("I should not see \"My Post 3\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
this.ScenarioCleanup();
}
@ -780,11 +804,11 @@ this.ScenarioSetup(scenarioInfo);
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("I can create a new blog with a percent sign in the title and it gets stripped out" +
" of the slug", ((string[])(null)));
#line 279
#line 291
this.ScenarioSetup(scenarioInfo);
#line 280
#line 292
testRunner.Given("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
#line 281
#line 293
testRunner.When("I go to \"admin/blogs/create\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden
TechTalk.SpecFlow.Table table27 = new TechTalk.SpecFlow.Table(new string[] {
@ -793,15 +817,15 @@ this.ScenarioSetup(scenarioInfo);
table27.AddRow(new string[] {
"Title.Title",
"My Blog"});
#line 282
#line 294
testRunner.And("I fill in", ((string)(null)), table27, "And ");
#line 285
#line 297
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 286
#line 298
testRunner.And("I go to \"admin/blogs\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 287
#line 299
testRunner.And("I follow \"My Blog\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 288
#line 300
testRunner.And("I follow \"New Post\" where class name has \"primaryAction\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
TechTalk.SpecFlow.Table table28 = new TechTalk.SpecFlow.Table(new string[] {
@ -813,15 +837,15 @@ this.ScenarioSetup(scenarioInfo);
table28.AddRow(new string[] {
"Body.Text",
"Hi there."});
#line 289
#line 301
testRunner.And("I fill in", ((string)(null)), table28, "And ");
#line 293
#line 305
testRunner.And("I hit \"Publish\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 294
#line 306
testRunner.And("I go to \"my-blog/my-post-with-a-sign\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 295
#line 307
testRunner.Then("I should see \"<h1[^>]*>.*?My Post with a % Sign.*?</h1>\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 296
#line 308
testRunner.And("I should see \"Hi there.\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
this.ScenarioCleanup();

View File

@ -163,7 +163,7 @@ Scenario: Creating and using date time fields in another culture
And I go to "Admin/ContentTypes/"
Then I should see "Event"
# Adding a Date field
# Adding a Date field and changing its settings
When I go to "Admin/ContentTypes/Edit/Event"
And I follow "Add Field"
And I fill in
@ -174,15 +174,15 @@ Scenario: Creating and using date time fields in another culture
And I hit "Save"
And I am redirected
Then I should see "The \"Date of the event\" field has been added."
# Date & Time are inputted based on current culture
When I have "fr-FR" as the default culture
And I go to "Admin/ContentTypes/Edit/Event"
When I go to "Admin/ContentTypes/Edit/Event"
And I fill in
| name | value |
| Fields[EventDate].DateTimeFieldSettings.Display | DateAndTime |
| Fields[EventDate].DateTimeFieldSettings.Required | true |
And I hit "Save"
# Date & Time are validated based on current culture
When I have "fr-FR" as the default culture
When I go to "Admin/Contents/Create/Event"
And I fill in
| name | value |

View File

@ -426,10 +426,8 @@ this.ScenarioSetup(scenarioInfo);
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 176
testRunner.Then("I should see \"The \\\"Date of the event\\\" field has been added.\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 179
testRunner.When("I have \"fr-FR\" as the default culture", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 180
testRunner.And("I go to \"Admin/ContentTypes/Edit/Event\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 177
testRunner.When("I go to \"Admin/ContentTypes/Edit/Event\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden
TechTalk.SpecFlow.Table table16 = new TechTalk.SpecFlow.Table(new string[] {
"name",
@ -440,10 +438,12 @@ this.ScenarioSetup(scenarioInfo);
table16.AddRow(new string[] {
"Fields[EventDate].DateTimeFieldSettings.Required",
"true"});
#line 181
#line 178
testRunner.And("I fill in", ((string)(null)), table16, "And ");
#line 185
#line 182
testRunner.And("I hit \"Save\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 185
testRunner.When("I have \"fr-FR\" as the default culture", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 186
testRunner.When("I go to \"Admin/Contents/Create/Event\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden

View File

@ -1,5 +1,6 @@
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
@ -16,6 +17,7 @@ namespace Orchard.Specs.Hosting.Orchard.Web {
}
protected void Application_Start() {
AntiForgeryConfig.SuppressXFrameOptionsHeader = true;
RegisterRoutes(RouteTable.Routes);
_container = OrchardStarter.CreateHostContainer(MvcSingletons);
_host = _container.Resolve<IOrchardHost>();
@ -29,6 +31,7 @@ namespace Orchard.Specs.Hosting.Orchard.Web {
protected void Application_BeginRequest() {
Context.Items["originalHttpContext"] = Context;
HttpContext.Current.Response.AddHeader("X-Frame-Options", "SAMEORIGIN");
_host.BeginRequest();
}

View File

@ -100,7 +100,6 @@
<add namespace="Orchard.Mvc.Html" />
</namespaces>
</pages>
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
</httpModules>
@ -155,34 +154,22 @@
<mimeMap fileExtension=".woff2" mimeType="font/woff2" />
</staticContent>
</system.webServer>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<logging level="Error" logLocation="App_data/Logs/Glimpse.log" />
<tabs>
<ignoredTypes>
<add type="Glimpse.Mvc.Tab.Views, Glimpse.Mvc5" />
<add type="Glimpse.Mvc.Tab.ModelBinding, Glimpse.Mvc5" />
<add type="Glimpse.Mvc.Tab.Metadata, Glimpse.Mvc5" />
<add type="Glimpse.AspNet.Tab.Cache, Glimpse.AspNet" />
<add type="Glimpse.AspNet.Tab.Routes, Glimpse.AspNet" />
<add type="Glimpse.AspNet.Tab.Session, Glimpse.AspNet" />
</ignoredTypes>
</tabs>
<inspectors>
<ignoredTypes>
<add type="Glimpse.Mvc.Inspector.ViewEngineInspector, Glimpse.Mvc5" />
<add type="Glimpse.Mvc.Inspector.DependencyInjectionInspector, Glimpse.Mvc5" />
<add type="Glimpse.Mvc.Inspector.ModelBinderInspector, Glimpse.Mvc5" />
<add type="Glimpse.AspNet.Inspector.RoutesInspector, Glimpse.AspNet" />
</ignoredTypes>
</inspectors>
<runtimePolicies>
<ignoredTypes>
<!-- Uncomment the line below to allow Glimpse to be enabled for remote requests -->
<!-- NOTE: If you uncomment this line, you can still restrict access to a set of whitelisted IP Address by adding the app setting `Orchard.Glimpse:WhitelistedIpAddresses` with a value of a semi colon separated IP Addresses to allow into the `appSettings` section of this file -->
<!--<add type="Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet" />-->
</ignoredTypes>
</runtimePolicies>
<!--For more information on how to configure Glimpse, please visit http://getglimpse.com/Help/Configuration or access {your site}/Glimpse.axd for even more details and a Configuration Tool to support you.-->
</glimpse>
<runtime>
<gcServer enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="App_Data/Dependencies" />
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.4000" newVersion="4.1.0.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,31 +1,13 @@
Feature: Media management
In order to reference images and such from content
As an author
I want to upload and manage files in a media folder
I want to access the Media Library
Scenario: Media admin is available
Given I have installed Orchard
And I have installed "Orchard.Media"
And I have installed "Orchard.MediaLibrary"
# Accessing the media page
When I go to "admin/media"
Then I should see "Media"
And the status should be 200 "OK"
# Creating a folder
When I go to "admin/media/create"
And I fill in
| name | value |
| Name | Hello World |
And I hit "Save"
And I am redirected
Then I should see "Media"
And I should see "Hello World"
And the status should be 200 "OK"
# Editing a media with limited rights
When I go to "admin/media/edit?name=..\..\bin&mediaPath=..\..\bin"
And I am redirected
Then I should see "Media"
And I should see "Editing failed: Invalid path"
# Accessing the Media Library page
When I go to "Admin/Orchard.MediaLibrary"
Then I should see "Media Library"
And the status should be 200 "OK"

View File

@ -33,7 +33,7 @@ namespace Orchard.Specs
{
testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Media management", " In order to reference images and such from content\r\n As an author\r\n I want to" +
" upload and manage files in a media folder", ProgrammingLanguage.CSharp, ((string[])(null)));
" access the Media Library", ProgrammingLanguage.CSharp, ((string[])(null)));
testRunner.OnFeatureStart(featureInfo);
}
@ -75,44 +75,13 @@ this.ScenarioSetup(scenarioInfo);
#line 7
testRunner.Given("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
#line 8
testRunner.And("I have installed \"Orchard.Media\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
testRunner.And("I have installed \"Orchard.MediaLibrary\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 11
testRunner.When("I go to \"admin/media\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
testRunner.When("I go to \"Admin/Orchard.MediaLibrary\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 12
testRunner.Then("I should see \"Media\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
testRunner.Then("I should see \"Media Library\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 13
testRunner.And("the status should be 200 \"OK\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 16
testRunner.When("I go to \"admin/media/create\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden
TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table1.AddRow(new string[] {
"Name",
"Hello World"});
#line 17
testRunner.And("I fill in", ((string)(null)), table1, "And ");
#line 20
testRunner.And("I hit \"Save\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 21
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 22
testRunner.Then("I should see \"Media\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 23
testRunner.And("I should see \"Hello World\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 24
testRunner.And("the status should be 200 \"OK\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 27
testRunner.When("I go to \"admin/media/edit?name=..\\..\\bin&mediaPath=..\\..\\bin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 28
testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 29
testRunner.Then("I should see \"Media\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 30
testRunner.And("I should see \"Editing failed: Invalid path\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 31
testRunner.And("the status should be 200 \"OK\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
this.ScenarioCleanup();
}

View File

@ -77,11 +77,8 @@
<Reference Include="FluentPath, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Orchard.FluentPath.1.0.0.1\lib\FluentPath.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.1.9, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.3.1\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Iesi.Collections, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<HintPath>..\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll</HintPath>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="IronRuby, Version=1.1.3.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1, processorArchitecture=MSIL">
<HintPath>..\packages\IronRuby.1.1.3\lib\IronRuby.dll</HintPath>

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Xml;
@ -14,6 +13,7 @@ using Orchard.Environment.Extensions.Folders;
using Orchard.Environment.Extensions.Loaders;
using Orchard.FileSystems.AppData;
using Orchard.FileSystems.WebSite;
using Orchard.Mvc;
using Orchard.Recipes.Events;
using Orchard.Recipes.Models;
using Orchard.Recipes.Services;
@ -93,6 +93,7 @@ namespace Orchard.Tests.Modules.Recipes.Services {
builder.RegisterType<RecipeParser>().As<IRecipeParser>();
builder.RegisterType<StubWebSiteFolder>().As<IWebSiteFolder>();
builder.RegisterType<CustomRecipeHandler>().As<IRecipeHandler>();
builder.RegisterType<StubHttpContextAccessor>().As<IHttpContextAccessor>();
}
public override void Init() {

View File

@ -1,7 +1,13 @@
using Autofac;
using System.IO;
using Autofac;
using NHibernate;
using NUnit.Framework;
using Orchard.Caching;
using Orchard.Data;
using Orchard.Localization.Records;
using Orchard.Localization.Services;
using Orchard.Mvc;
using Orchard.Tests.ContentManagement;
using Orchard.Tests.Stubs;
namespace Orchard.Tests.Localization {
@ -10,25 +16,56 @@ namespace Orchard.Tests.Localization {
private IContainer _container;
private IWorkContextStateProvider _currentCultureStateProvider;
private WorkContext _workContext;
private ISessionFactory _sessionFactory;
private ISession _session;
private string _databaseFileName;
private const string _testCulture = "fr-CA";
[TestFixtureSetUp]
public void InitFixture() {
_databaseFileName = Path.GetTempFileName();
_sessionFactory = DataUtility.CreateSessionFactory(
_databaseFileName,
typeof(CultureRecord));
}
[SetUp]
public void Init() {
_session = _sessionFactory.OpenSession();
var builder = new ContainerBuilder();
_workContext = new StubWorkContext();
builder.RegisterInstance(new StubCultureSelector("fr-CA")).As<ICultureSelector>();
builder.RegisterInstance(new StubCultureSelector(_testCulture)).As<ICultureSelector>();
builder.RegisterInstance(new StubHttpContext("~/"));
builder.RegisterInstance(_workContext);
builder.RegisterType<StubHttpContextAccessor>().As<IHttpContextAccessor>();
builder.RegisterType<CurrentCultureWorkContext>().As<IWorkContextStateProvider>();
builder.RegisterType<DefaultCultureManager>().As<ICultureManager>();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
builder.RegisterType<Signals>().As<ISignals>().SingleInstance();
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
_session = _sessionFactory.OpenSession();
builder.RegisterInstance(new TestTransactionManager(_session)).As<ITransactionManager>();
_container = builder.Build();
_currentCultureStateProvider = _container.Resolve<IWorkContextStateProvider>();
_container.Resolve<ICultureManager>().AddCulture(_testCulture);
}
[TearDown]
public void Term() {
_session.Close();
}
[TestFixtureTearDown]
public void TermFixture() {
File.Delete(_databaseFileName);
}
[Test]
public void CultureManagerReturnsCultureFromSelectors() {
var actualCulture = _currentCultureStateProvider.Get<string>("CurrentCulture")(_workContext);
var expectedCulture = "fr-CA";
Assert.That(actualCulture, Is.EqualTo(expectedCulture));
Assert.That(actualCulture, Is.EqualTo(_testCulture));
}
}
}

View File

@ -142,7 +142,7 @@
<HintPath>..\..\lib\sqlce\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>

View File

@ -1,10 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using System;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.FileSystems.Media;
@ -215,8 +214,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void GetFileFailsInInvalidPath() {
Assert.That(() => _storageProvider.GetFile(@"../InvalidFile.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.GetFile(@"../../InvalidFile.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.GetFile(@"../InvalidFile.txt"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.GetFile(@"../../InvalidFile.txt"), Throws.InstanceOf(typeof(OrchardException)));
// Valid get one level up within the storage provider domain
_storageProvider.CreateFile(@"test.txt");
@ -226,8 +225,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void ListFilesFailsInInvalidPath() {
Assert.That(() => _storageProvider.ListFiles(@"../InvalidFolder"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.ListFiles(@"../../InvalidFolder"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.ListFiles(@"../InvalidFolder"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.ListFiles(@"../../InvalidFolder"), Throws.InstanceOf(typeof(OrchardException)));
// Valid get one level up within the storage provider domain
Assert.That(_storageProvider.ListFiles(@"SubFolder1"), Is.Not.Null);
@ -236,8 +235,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void ListFoldersFailsInInvalidPath() {
Assert.That(() => _storageProvider.ListFolders(@"../InvalidFolder"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.ListFolders(@"../../InvalidFolder"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.ListFolders(@"../InvalidFolder"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.ListFolders(@"../../InvalidFolder"), Throws.InstanceOf(typeof(OrchardException)));
// Valid get one level up within the storage provider domain
Assert.That(_storageProvider.ListFolders(@"SubFolder1"), Is.Not.Null);
@ -255,8 +254,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void CreateFolderFailsInInvalidPath() {
Assert.That(() => _storageProvider.CreateFolder(@"../InvalidFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.CreateFolder(@"../../InvalidFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.CreateFolder(@"../InvalidFolder1"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.CreateFolder(@"../../InvalidFolder1"), Throws.InstanceOf(typeof(OrchardException)));
// Valid create one level up within the storage provider domain
_storageProvider.CreateFolder(@"SubFolder1\..\ValidFolder1");
@ -265,8 +264,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void DeleteFolderFailsInInvalidPath() {
Assert.That(() => _storageProvider.DeleteFolder(@"../InvalidFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.DeleteFolder(@"../../InvalidFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.DeleteFolder(@"../InvalidFolder1"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.DeleteFolder(@"../../InvalidFolder1"), Throws.InstanceOf(typeof(OrchardException)));
// Valid create one level up within the storage provider domain
Assert.That(GetFolder("SubFolder1"), Is.Not.Null);
@ -277,8 +276,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void RenameFolderFailsInInvalidPath() {
Assert.That(GetFolder(@"SubFolder1/SubSubFolder1"), Is.Not.Null);
Assert.That(() => _storageProvider.RenameFolder(@"SubFolder1", @"../SubSubFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.RenameFolder(@"SubFolder1", @"../../SubSubFolder1"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.RenameFolder(@"SubFolder1", @"../SubSubFolder1"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.RenameFolder(@"SubFolder1", @"../../SubSubFolder1"), Throws.InstanceOf(typeof(OrchardException)));
// Valid move one level up within the storage provider domain
_storageProvider.RenameFolder(@"SubFolder1\SubSubFolder1", @"SubFolder1\..\SubSubFolder1");
@ -291,8 +290,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void DeleteFileFailsInInvalidPath() {
Assert.That(() => _storageProvider.DeleteFile(@"../test.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.DeleteFile(@"../test.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.DeleteFile(@"../test.txt"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.DeleteFile(@"../test.txt"), Throws.InstanceOf(typeof(OrchardException)));
// Valid move one level up within the storage provider domain
_storageProvider.CreateFile(@"test.txt");
@ -308,8 +307,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void RenameFileFailsInInvalidPath() {
Assert.That(() => _storageProvider.RenameFile(@"../test.txt", "invalid.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.RenameFile(@"../test.txt", "invalid.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.RenameFile(@"../test.txt", "invalid.txt"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.RenameFile(@"../test.txt", "invalid.txt"), Throws.InstanceOf(typeof(OrchardException)));
// Valid move one level up within the storage provider domain
_storageProvider.CreateFile(@"test.txt");
@ -322,8 +321,8 @@ namespace Orchard.Tests.Storage {
[Test]
public void CreateFileFailsInInvalidPath() {
Assert.That(() => _storageProvider.CreateFile(@"../InvalidFolder1.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.CreateFile(@"../../InvalidFolder1.txt"), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.CreateFile(@"../InvalidFolder1.txt"), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.CreateFile(@"../../InvalidFolder1.txt"), Throws.InstanceOf(typeof(OrchardException)));
// Valid create one level up within the storage provider domain
_storageProvider.CreateFile(@"SubFolder1\..\ValidFolder1.txt");
@ -335,8 +334,8 @@ namespace Orchard.Tests.Storage {
_storageProvider.CreateFile(@"test.txt");
using (Stream stream = GetFile("test.txt").OpenRead()) {
Assert.That(() => _storageProvider.SaveStream(@"../newTest.txt", stream), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.SaveStream(@"../../newTest.txt", stream), Throws.InstanceOf(typeof(ArgumentException)));
Assert.That(() => _storageProvider.SaveStream(@"../newTest.txt", stream), Throws.InstanceOf(typeof(OrchardException)));
Assert.That(() => _storageProvider.SaveStream(@"../../newTest.txt", stream), Throws.InstanceOf(typeof(OrchardException)));
// Valid create one level up within the storage provider domain
_storageProvider.SaveStream(@"SubFolder1\..\newTest.txt", stream);

View File

@ -9,6 +9,14 @@
</Properties>
</Component>
<Component Type="Orchard.DisplayManagement.Descriptors.DefaultShapeTableManager">
<Properties>
<!-- Set Value="true" to enable an optimization in the sorting step of the ShapeAlterations.
Warning: Rendered results should not be affected, but intermediate steps might. -->
<Property Name="GroupByFeatures" Value="false"/>
</Properties>
</Component>
<Component Type="Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy.PlacementFileParser">
<Properties>
<!-- Set Value="true" to disable Placement files monitoring (Placement.info) -->
@ -81,6 +89,14 @@
</Properties>
</Component>
<Component Type="Orchard.Environment.Extensions.ExtensionManager">
<Properties>
<!-- Set Value="true" to disable parallel loading of feature assemblies. This may boost application startup times by
decreasing the number of parallel tasks the application attempts to start. -->
<Property Name="ParallelizationDisabled" Value="false"/>
</Properties>
</Component>
<Component Type="Orchard.Data.SessionConfigurationCache">
<Properties>
<!-- Set Value="true" to disable session configuration cache (mappings.bin). Recommended when using multiple instances. -->

View File

@ -10,6 +10,15 @@ namespace Orchard.Core.Common {
public class Migrations : DataMigrationImpl {
private readonly IRepository<IdentityPartRecord> _identityPartRepository;
/// <summary>
/// When upgrading from "1.10.x" branch code committed after 1.10.3 to "dev" branch code or 1.11, merge
/// conflicts between "1.10.x" and "dev" caused by running the same migration steps in a different order need to
/// be resolved by instructing this migration to decide which steps need to be executed. If you're upgrading
/// under these conditions and your pre-upgrade migration version is 7 or 8, use HostComponents.config to
/// override one of these properties to true.
/// </summary>
public bool IsUpgradingFromOrchard_1_10_x_Version_7 { get; set; }
public bool IsUpgradingFromOrchard_1_10_x_Version_8 { get; set; }
public Migrations(IRepository<IdentityPartRecord> identityPartRepository) {
_identityPartRepository = identityPartRepository;
@ -35,7 +44,7 @@ namespace Orchard.Core.Common {
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_{nameof(CommonPartRecord.ModifiedUtc)}", nameof(CommonPartRecord.ModifiedUtc));
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_{nameof(CommonPartRecord.PublishedUtc)}", nameof(CommonPartRecord.PublishedUtc));
// This originally in UpdateFrom7
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_Container_id","Container_id");
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_Container_id", "Container_id");
// This originally in UpdateFrom8
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByCreation",
nameof(CommonPartRecord.OwnerId),
@ -66,6 +75,7 @@ namespace Orchard.Core.Common {
.ContentPartRecord()
.Column<string>("Identifier", column => column.WithLength(255)))
.AlterTable(nameof(IdentityPartRecord), table => table
// This originally in UpdateFrom6
.CreateIndex($"IDX_{nameof(IdentityPartRecord)}_{nameof(IdentityPartRecord.Identifier)}", nameof(IdentityPartRecord.Identifier)));
ContentDefinitionManager.AlterPartDefinition("BodyPart", builder => builder
@ -155,34 +165,34 @@ namespace Orchard.Core.Common {
}
public int UpdateFrom6() {
SchemaBuilder.AlterTable(nameof(IdentityPartRecord), table => table
.CreateIndex($"IDX_{nameof(IdentityPartRecord)}_{nameof(IdentityPartRecord.Identifier)}", nameof(IdentityPartRecord.Identifier)));
AddIndexForIdentityPartRecordIdentifier();
return 7;
}
public int UpdateFrom7() {
// The Container_Id is basically a foreign key, used in several queries
SchemaBuilder.AlterTable(nameof(CommonPartRecord), table => {
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_Container_id",
"Container_id");
});
AddIndexForCommonPartRecordContainerId();
return 8;
}
public int UpdateFrom8() {
// Studying SQL Server query execution plans we noticed that when the system
// tries to find content items for requests such as
// "The items of type TTT owned by me, ordered from the most recent"
// the existing indexes are not used. SQL Server does an index scan on the
// Primary key for CommonPartRecord. This may lead to annoying deadlocks when
// there are two concurrent transactions that are doing both this kind of query
// as well as an update (or insert) in the CommonPartRecord.
// Tests show that this can be easily fixed by adding a non-clustered index
// with these keys: OwnerId, {one of PublishedUTC, ModifiedUTC, CreatedUTC}.
// That means we need three indexes (one for each DateTime) to support ordering
// on either of them.
if (IsUpgradingFromOrchard_1_10_x_Version_7) {
AddIndexForIdentityPartRecordIdentifier();
}
else if (IsUpgradingFromOrchard_1_10_x_Version_8) {
AddIndexForCommonPartRecordContainerId();
}
else {
// This change was originally UpdateFrom6 on 1.10.x and UpdateFrom8 on dev.
// Studying SQL Server query execution plans we noticed that when the system tries to find content items for
// requests such as "The items of type TTT owned by me, ordered from the most recent" the existing indexes
// are not used. SQL Server does an index scan on the Primary key for CommonPartRecord. This may lead to
// annoying deadlocks when there are two concurrent transactions that are doing both this kind of query as
// well as an update (or insert) in the CommonPartRecord. Tests show that this can be easily fixed by adding
// a non-clustered index with these keys: OwnerId, {one of PublishedUTC, ModifiedUTC, CreatedUTC}. That
// means we need three indexes (one for each DateTime) to support ordering on either of them.
// The queries we analyzed look like (in pseudo sql)
// SELECT TOP (N) *
@ -197,19 +207,35 @@ namespace Orchard.Core.Common {
// and this_.Published = 1
// ORDER BY
// commonpart2_PublishedUtc desc
var createdUtcIndexName = $"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByCreation";
var modifiedUtcIndexName = $"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByModification";
var publishedUtcIndexName = $"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByPublication";
SchemaBuilder.AlterTable(nameof(CommonPartRecord), table => {
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByCreation",
nameof(CommonPartRecord.OwnerId),
nameof(CommonPartRecord.CreatedUtc));
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByModification",
nameof(CommonPartRecord.OwnerId),
nameof(CommonPartRecord.ModifiedUtc));
table.CreateIndex($"IDX_{nameof(CommonPartRecord)}_OwnedBy_ByPublication",
nameof(CommonPartRecord.OwnerId),
nameof(CommonPartRecord.PublishedUtc));
table.CreateIndex(createdUtcIndexName, nameof(CommonPartRecord.OwnerId), nameof(CommonPartRecord.CreatedUtc));
table.CreateIndex(modifiedUtcIndexName, nameof(CommonPartRecord.OwnerId), nameof(CommonPartRecord.ModifiedUtc));
table.CreateIndex(publishedUtcIndexName, nameof(CommonPartRecord.OwnerId), nameof(CommonPartRecord.PublishedUtc));
});
}
return 9;
}
// This change was originally UpdateFrom7 on 1.10.x and UpdateFrom6 on dev.
private void AddIndexForIdentityPartRecordIdentifier() {
var indexName = $"IDX_{nameof(IdentityPartRecord)}_{nameof(IdentityPartRecord.Identifier)}";
SchemaBuilder.AlterTable(nameof(IdentityPartRecord), table => table.CreateIndex(
indexName,
nameof(IdentityPartRecord.Identifier)));
}
// This change was originally UpdateFrom8 on 1.10.x and UpdateFrom7 on dev.
private void AddIndexForCommonPartRecordContainerId() {
var indexName = $"IDX_{nameof(CommonPartRecord)}_Container_id";
// Container_Id is used in several queries like a foreign key.
SchemaBuilder.AlterTable(nameof(CommonPartRecord), table => table.CreateIndex(indexName, "Container_id"));
}
}
}

View File

@ -35,7 +35,7 @@ namespace Orchard.Core.Common.OwnerEditor {
protected override DriverResult Editor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
var currentUser = _authenticationService.GetAuthenticatedUser();
if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, currentUser, part)) {
if (!_authorizationService.TryCheckAccess(OwnerEditorPermissions.MayEditContentOwner, currentUser, part)) {
return null;
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Environment.Extensions.Models;
using Orchard.Security;
using Orchard.Security.Permissions;
namespace Orchard.Core.Common.OwnerEditor {
public class OwnerEditorPermissions : IPermissionProvider {
public static readonly Permission MayEditContentOwner = new Permission {
Description = "Edit the Owner of content items",
Name = "MayEditContentOwner",
ImpliedBy = new[] { StandardPermissions.SiteOwner } };
public virtual Feature Feature { get; set; }
public IEnumerable<PermissionStereotype> GetDefaultStereotypes() {
return new[] {new PermissionStereotype {
Name = "Administrator",
Permissions = new[] { MayEditContentOwner }
} };
}
public IEnumerable<Permission> GetPermissions() {
return new[] { MayEditContentOwner };
}
}
}

View File

@ -9,7 +9,7 @@
@Html.ValidationMessageFor(m => m.Text)
}
else {
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.Settings.Flavor, Required: Model.Settings.Required, ContentItem: Model.ContentItem, Placeholder: Model.Settings.Placeholder)
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.Settings.Flavor, Required: Model.Settings.Required, ContentItem: Model.ContentItem, Placeholder: Model.Settings.Placeholder, Field: Model.Field)
}
@if (HasText(Model.Settings.Hint)) {
<span class="hint">@Model.Settings.Hint</span>

View File

@ -2,6 +2,6 @@
@using Orchard.Core.Common.ViewModels;
<fieldset>
<label>@T("Body")</label>
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.EditorFlavor, Required: false, AutoFocus: false, ContentItem: Model.BodyPart.ContentItem)
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.EditorFlavor, Required: false, AutoFocus: false, ContentItem: Model.BodyPart.ContentItem, Part: Model.BodyPart)
@Html.ValidationMessageFor(m => m.Text)
</fieldset>

View File

@ -1,4 +1,5 @@
using System.Web;
using System.Collections.Generic;
using System.Web;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Navigation.Models;
@ -11,18 +12,36 @@ namespace Orchard.Core.Navigation.Services {
public DefaultMenuProvider(IContentManager contentManager) {
_contentManager = contentManager;
_menuPartsMemory = new Dictionary<int, IEnumerable<MenuPart>>();
}
// Prevent doing the same query for MenuParts more than once on a same request
// in case we are building the same menu several times.
private Dictionary<int, IEnumerable<MenuPart>> _menuPartsMemory;
public void GetMenu(IContent menu, NavigationBuilder builder) {
var menuParts = _contentManager
if (!_menuPartsMemory.ContainsKey(menu.Id)) {
_menuPartsMemory[menu.Id] = _contentManager
.Query<MenuPart, MenuPartRecord>()
.Where(x => x.MenuId == menu.Id)
.List();
}
var menuParts = _menuPartsMemory[menu.Id];
foreach (var menuPart in menuParts) {
if (menuPart != null) {
var part = menuPart;
var showItem = true;
// If the menu item is a ContentMenuItemPart (from Orchard.ContentPicker), check the ContentItem is published.
// If there is no published version of the ContentItem, the item must not be added to NavigationBuilder.
var cmip = ((dynamic)part).ContentMenuItemPart;
if (cmip != null) {
showItem = cmip.Content != null;
}
if (showItem) {
string culture = null;
// fetch the culture of the content menu item, if any
var localized = part.As<ILocalizableAspect>();
@ -38,4 +57,5 @@ namespace Orchard.Core.Navigation.Services {
}
}
}
}
}

View File

@ -63,10 +63,14 @@
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="NHibernate, Version=5.3.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<HintPath>..\..\packages\NHibernate.5.3.10\lib\net461\NHibernate.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
@ -99,6 +103,7 @@
<Compile Include="Common\DateEditor\DateEditorSettings.cs" />
<Compile Include="Common\Extensions\CommonMetaDataExtensions.cs" />
<Compile Include="Common\Extensions\ContentItemExtensions.cs" />
<Compile Include="Common\OwnerEditor\OwnerEditorPermissions.cs" />
<Compile Include="Common\OwnerEditor\OwnerEditorSettings.cs" />
<Compile Include="Common\OwnerEditor\OwnerEditorDriver.cs" />
<Compile Include="Common\DateEditor\DateEditorDriver.cs" />
@ -605,13 +610,11 @@
</ItemGroup>
<ItemGroup>
<Content Include="Contents\Views\Parts.Contents.Clone.SummaryAdmin.cshtml" />
<Content Include="Navigation\Views\Admin\Edit.cshtml" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Navigation\Views\Admin\Edit.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@ -5,4 +5,5 @@
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net48" />
<package id="NHibernate" version="5.3.10" targetFramework="net48" />
</packages>

View File

@ -55,8 +55,8 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.1.9, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\SharpZipLib.1.3.1\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=3.0.3.0, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll</HintPath>

View File

@ -29,6 +29,7 @@
<compilation targetFramework="4.8">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />

View File

@ -89,6 +89,18 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<dataCacheClients>

View File

@ -42,7 +42,7 @@ namespace Orchard.Blogs {
if (singleBlog != null)
menu.Add(T("New Post"), "1.1",
item =>
item.Action("Create", "BlogPostAdmin", new {area = "Orchard.Blogs", blogId = singleBlog.Id}).Permission(Permissions.MetaListOwnBlogs));
item.Action("Create", "BlogPostAdmin", new { area = "Orchard.Blogs", blogId = singleBlog.Id }).Permission(Permissions.MetaListOwnBlogs));
menu.Add(T("New Blog"), "1.2",
item =>

View File

@ -0,0 +1,40 @@
using Orchard.Blogs.Services;
using Orchard.Localization;
using Orchard.Security;
using Orchard.UI.Navigation;
namespace Orchard.Blogs {
public class BlogPostsLocalNavigationProvider : INavigationProvider {
private readonly IBlogService _blogService;
private readonly IAuthorizationService _authorizationService;
private readonly IWorkContextAccessor _workContextAccessor;
public BlogPostsLocalNavigationProvider(
IBlogService blogService,
IAuthorizationService authorizationService,
IWorkContextAccessor workContextAccessor) {
T = NullLocalizer.Instance;
_blogService = blogService;
_authorizationService = authorizationService;
_workContextAccessor = workContextAccessor;
}
public Localizer T { get; set; }
public string MenuName {
get { return "blogposts-navigation"; }
}
public void GetNavigation(NavigationBuilder builder) {
var blogId = 0;
int.TryParse(_workContextAccessor.GetContext().HttpContext.Request.RequestContext.RouteData.Values["blogId"]?.ToString(), out blogId);
if (blogId > 0) {
builder.Add(T("Blog posts"),
item => item.Action("Item", "BlogAdmin", new { area = "Orchard.Blogs", blogId })
.LocalNav()
.Permission(Permissions.MetaListOwnBlogs));
}
}
}
}

View File

@ -2,7 +2,6 @@ using System.Linq;
using System.Web.Mvc;
using Orchard.Blogs.Extensions;
using Orchard.Blogs.Models;
using Orchard.Blogs.Routing;
using Orchard.Blogs.Services;
using Orchard.ContentManagement;
using Orchard.Data;
@ -13,6 +12,7 @@ using Orchard.UI.Admin;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
using Orchard.Settings;
using System.Collections.Generic;
namespace Orchard.Blogs.Controllers {
@ -21,6 +21,7 @@ namespace Orchard.Blogs.Controllers {
private readonly IBlogService _blogService;
private readonly IBlogPostService _blogPostService;
private readonly IContentManager _contentManager;
private readonly INavigationManager _navigationManager;
private readonly ITransactionManager _transactionManager;
private readonly ISiteService _siteService;
@ -29,6 +30,7 @@ namespace Orchard.Blogs.Controllers {
IBlogService blogService,
IBlogPostService blogPostService,
IContentManager contentManager,
INavigationManager navigationManager,
ITransactionManager transactionManager,
ISiteService siteService,
IShapeFactory shapeFactory) {
@ -36,6 +38,7 @@ namespace Orchard.Blogs.Controllers {
_blogService = blogService;
_blogPostService = blogPostService;
_contentManager = contentManager;
_navigationManager = navigationManager;
_transactionManager = transactionManager;
_siteService = siteService;
T = NullLocalizer.Instance;
@ -179,6 +182,18 @@ namespace Orchard.Blogs.Controllers {
var totalItemCount = _blogPostService.PostCount(blogPart, VersionOptions.Latest);
blog.Content.Add(Shape.Pager(pager).TotalItemCount(totalItemCount), "Content:after");
// Adds LocalMenus;
var menuItems = _navigationManager.BuildMenu("blogposts-navigation");
var request = Services.WorkContext.HttpContext.Request;
// Set the currently selected path
Stack<MenuItem> selectedPath = NavigationHelper.SetSelectedPath(menuItems, request, request.RequestContext.RouteData);
// Populate local nav
dynamic localMenuShape = Shape.LocalMenu().MenuName("local-admin");
// NavigationHelper.PopulateLocalMenu(Shape, localMenuShape, localMenuShape, selectedPath);
NavigationHelper.PopulateLocalMenu(Shape, localMenuShape, localMenuShape, menuItems);
Services.WorkContext.Layout.LocalNavigation.Add(localMenuShape);
return View(blog);
}

View File

@ -96,6 +96,7 @@
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="BlogsLocalizationExtensions\Handlers\BlogPostPartHandler.cs" />
<Compile Include="BlogPostLocalNavigationProvider.cs" />
<Compile Include="BlogsLocalizationExtensions\Migrations\Migrations.cs" />
<Compile Include="Commands\BlogWidgetCommands.cs" />
<Compile Include="Controllers\RemoteBlogPublishingController.cs" />
@ -155,10 +156,13 @@
<Content Include="Content\Admin\images\scheduled.gif" />
<Content Include="Module.txt" />
<Content Include="Scripts\orchard-blogs-archives.js" />
<Content Include="Scripts\orchard-blogs-archives.min.js" />
<Content Include="Styles\images\menu.blog.png" />
<Content Include="Styles\menu.blog-admin.css" />
<Content Include="Styles\orchard-blogs-admin.css" />
<Content Include="Styles\orchard-blogs-admin.min.css" />
<Content Include="Styles\orchard-blogs-archives.css" />
<Content Include="Styles\orchard-blogs-archives.min.css" />
<Content Include="Views\BlogAdmin\Create.cshtml" />
<Content Include="Views\BlogAdmin\Edit.cshtml" />
<Content Include="Views\BlogAdmin\Item.cshtml" />

View File

@ -4,10 +4,14 @@ namespace Orchard.Blogs {
public class ResourceManifest : IResourceManifestProvider {
public void BuildManifests(ResourceManifestBuilder builder) {
var manifest = builder.Add();
manifest.DefineStyle("BlogsAdmin").SetUrl("orchard-blogs-admin.css");
manifest.DefineStyle("BlogsArchives").SetUrl("orchard-blogs-archives.css");
manifest.DefineStyle("BlogsAdmin")
.SetUrl("orchard-blogs-admin.min.css", "orchard-blogs-admin.css");
manifest.DefineStyle("BlogsArchives")
.SetUrl("orchard-blogs-archives.min.css", "orchard-blogs-archives.css");
manifest.DefineScript("BlogsArchives").SetUrl("orchard-blogs-archives.js").SetDependencies("jQuery");
manifest.DefineScript("BlogsArchives")
.SetUrl("orchard-blogs-archives.min.js", "orchard-blogs-archives.js")
.SetDependencies("jQuery");
}
}
}

View File

@ -0,0 +1 @@
!function($){$((function(){$(".archives ul.years li.previous").each((function(){$(this).click((function(ev){ev&&!$(ev.target).not("a").size()||($(this).toggleClass("open"),$(this).find("h4>span").toggle(),$(this).children("ul").toggle())}))}))}))}(jQuery);

View File

@ -0,0 +1 @@
#main .blog-description p{margin-bottom:1em}

View File

@ -0,0 +1 @@
.archives h3{margin-bottom:0}.archives ul{margin:0;padding:0}.archives ul .archives li{list-style-type:none}.archives ul.years li{list-style-type:none;margin:.6em 0 0}.archives ul.archiveMonthList li{margin:.2em 0}.archives ul.archiveMonthList li.first{margin-top:0}.archives ul.archiveMonthList li.last{margin-bottom:0}.archives ul.years li.previous h4 span{display:none}html.dyn .archives ul.years li.previous h4 span{display:inline}html.dyn .archives ul.years li h4,html.dyn .archives ul.years li ul{margin:.2em .2ex}html.dyn .archives ul.years li.previous h4:before{content:"⇓ "}html.dyn .archives ul.years li.previous{cursor:pointer;padding:.1em .2ex .2em 2ex;margin:0 -2ex}html.dyn .archives ul.years li.previous.hover{background-position:0 6px}html.dyn .archives ul.years li.previous.open h4:before{content:"⇑ "}html.dyn .archives ul.years li.previous.open.hover{background-position:0 6px}html.dyn .archives ul.years li.previous ul{display:none;margin-left:2ex}

View File

@ -1,5 +1,5 @@
@{
Layout.Title = T("Manage Blog").ToString();
}
@* Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type *@
@Display(Model)
@* Model is a Shape, calling Display() so that it is rendered using the most specific template for its Shape type *@
@Display(Model)

View File

@ -71,7 +71,6 @@
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Routing" />
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">

View File

@ -89,8 +89,7 @@ namespace Orchard.ContentPicker.Drivers {
if (String.IsNullOrEmpty(model.SelectedIds)) {
field.Ids = new int[0];
}
else {
} else {
field.Ids = model.SelectedIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
}
@ -102,16 +101,20 @@ namespace Orchard.ContentPicker.Drivers {
}
protected override void Importing(ContentPart part, Fields.ContentPickerField field, ImportContentContext context) {
// If nothing about the field is inside the context, field is not modified.
// For this reason, check if the current element is inside the ImportContentContext.
var element = context.Data.Element(field.FieldDefinition.Name + "." + field.Name);
if (element != null) {
var contentItemIds = context.Attribute(field.FieldDefinition.Name + "." + field.Name, "ContentItems");
if (contentItemIds != null) {
field.Ids = contentItemIds.Split(',')
.Select(context.GetItemFromSession)
.Select(contentItem => contentItem.Id).ToArray();
}
else {
} else {
field.Ids = new int[0];
}
}
}
protected override void Exporting(ContentPart part, Fields.ContentPickerField field, ExportContentContext context) {
if (field.Ids.Any()) {

View File

@ -12,13 +12,14 @@
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset>
<fieldset>
<label for="DisplayName" class="required">@T("Display Name")</label>
@Html.TextBoxFor(m => m.DisplayName, new {@class = "text medium", autofocus = "autofocus"})
@Html.TextBoxFor(m => m.DisplayName, new { @class = "text medium", autofocus = "autofocus" })
<span class="hint">@T("Name of the field as it will be displayed in screens.")</span>
<span class="hint">@T("Content Field Id: {0}", Model.Name)</span>
@Html.HiddenFor(m => m.Name)
</fieldset>
</fieldset>
<fieldset>
<button class="primaryAction" type="submit" name="submit.Save" value="Save">@T("Save")</button>
@if (!String.IsNullOrWhiteSpace(returnUrl) && Request.IsLocalUrl(returnUrl)) {

View File

@ -11,6 +11,7 @@
<div class="properties">
<h3>@Model.DisplayName</h3>
@if (!string.IsNullOrWhiteSpace(stereotype)) { <text><span class="stereotype" title="Stereotype">- @stereotype</span></text> }
@if (!Model.DisplayName.Equals(Model.Name, StringComparison.OrdinalIgnoreCase)) { <text><span class="hint" title="@T("Technical name")">@T("Content Type name: {0}", Model.Name)</span></text> }
@if (settings.Creatable) {
<p class="pageStatus">@Html.ActionLink(T("Create New {0}", Html.Raw(Model.DisplayName)).Text, "Create", new {area = "Contents", id = Model.Name})</p>

View File

@ -17,17 +17,17 @@
}
// Code Mirror
Script.Include("CodeMirror/codemirror.js");
Script.Include("CodeMirror/codemirror.js").AtHead();
Style.Include("CodeMirror/codemirror.css");
Script.Include("CodeMirror/razor.js");
Script.Include("CodeMirror/razor.js").AtHead();
Style.Include("CodeMirror/razor.css");
Script.Include("CodeMirror/javascript.js");
Style.Include("CodeMirror/javascript.css");
Script.Include("CodeMirror/css.js");
Script.Include("CodeMirror/javascript.js").AtHead();
Style.Include("CodeMirror/javascript.css").AtHead();
Script.Include("CodeMirror/css.js").AtHead();
Style.Include("CodeMirror/css.css");
Script.Include("CodeMirror/htmlmixed.js");
Script.Include("CodeMirror/htmlmixed.js").AtHead();
Script.Include("jquery.tmpl.min.js");
Script.Include("jquery.tmpl.min.js").AtHead();
}
<script class="shape-tracing-wrapper" shape-id="@Model.ShapeId" shape-type="@Model.Metadata.Type" shape-hint="@Model.Hint"></script>@Display(Model.Metadata.ChildContent)<script class="shape-tracing-wrapper" end-of="@Model.ShapeId"></script>

View File

@ -71,7 +71,7 @@ namespace Orchard.Fields.Drivers {
protected override void Describe(DescribeMembersContext context) {
context
.Member(null, typeof(Boolean), T("Value"), T("The boolean value of the field."))
.Member(null, typeof(Boolean?), T("Value"), T("The boolean value of the field."))
.Enumerate<BooleanField>(() => field => new [] { field.Value })
;
}

View File

@ -102,7 +102,13 @@ namespace Orchard.Fields.Drivers {
}
protected override void Importing(ContentPart part, NumericField field, ImportContentContext context) {
context.ImportAttribute(field.FieldDefinition.Name + "." + field.Name, "Value", v => field.Value = decimal.Parse(v, CultureInfo.InvariantCulture), () => field.Value = (decimal?)null);
Action empty = (() => field.Value = (decimal?)null);
var element = context.Data.Element(field.FieldDefinition.Name + "." + field.Name);
// If element is not in the ImportContentContext, field must not be reset.
if (element == null) {
empty = () => { };
}
context.ImportAttribute(field.FieldDefinition.Name + "." + field.Name, "Value", v => field.Value = decimal.Parse(v, CultureInfo.InvariantCulture), empty);
}
protected override void Exporting(ContentPart part, NumericField field, ExportContentContext context) {

View File

@ -13,17 +13,17 @@
case SelectionMode.Radiobutton:
if (settings.Optional) {
<div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-unknown" value="" @if(!Model.Value.HasValue) { <text>checked="checked"</text> } />
<label for="radio-unknown" class="forcheckbox">@T.Encode(settings.NotSetLabel)</label>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="@Html.FieldIdFor(m => m.Value)-radio-unknown" value="" @if(!Model.Value.HasValue) { <text>checked="checked"</text> } />
<label for="@Html.FieldIdFor(m => m.Value)-radio-unknown" class="forcheckbox">@T.Encode(settings.NotSetLabel)</label>
</div>
}
<div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-true" value="true" @if (Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } />
<label for="radio-true" class="forcheckbox">@T.Encode(settings.OnLabel)</label>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="@Html.FieldIdFor(m => m.Value)-radio-true" value="true" @if (Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } />
<label for="@Html.FieldIdFor(m => m.Value)-radio-true" class="forcheckbox">@T.Encode(settings.OnLabel)</label>
</div>
<div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-false" value="false" @if (Model.Value.HasValue && !Model.Value.Value) { <text>checked="checked"</text> } />
<label for="radio-false" class="forcheckbox">@T.Encode(settings.OffLabel)</label>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="@Html.FieldIdFor(m => m.Value)-radio-false" value="false" @if (Model.Value.HasValue && !Model.Value.Value) { <text>checked="checked"</text> } />
<label for="@Html.FieldIdFor(m => m.Value)-radio-false" class="forcheckbox">@T.Encode(settings.OffLabel)</label>
</div>
break;
case SelectionMode.Dropdown:

View File

@ -44,9 +44,8 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\lib\moq\Moq.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\..\..\..\..\lib\nunit\nunit.framework.dll</HintPath>

View File

@ -29,6 +29,7 @@
<compilation targetFramework="4.8">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />

View File

@ -15,7 +15,8 @@ namespace Orchard.Layouts.Drivers {
protected override EditorResult OnBuildEditor(Html element, ElementEditorContext context) {
var viewModel = new HtmlEditorViewModel {
Text = element.Content
Text = element.Content,
Part = ((dynamic)context.Content.ContentItem).LayoutPart
};
var editor = context.ShapeFactory.EditorTemplate(TemplateName: "Elements.Html", Model: viewModel);

View File

@ -69,7 +69,6 @@
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>

View File

@ -1,5 +1,8 @@
namespace Orchard.Layouts.ViewModels {
using Orchard.ContentManagement;
namespace Orchard.Layouts.ViewModels {
public class HtmlEditorViewModel {
public string Text { get; set; }
public ContentPart Part { get; set; }
}
}

View File

@ -1,5 +1,5 @@
@model Orchard.Layouts.ViewModels.HtmlEditorViewModel
<fieldset>
@Html.LabelFor(m => m.Text, T("HTML"))
@Display.Body_Editor(EditorFlavor: "html", Text: Model.Text, AutoFocus: true)
@Display.Body_Editor(EditorFlavor: "html", Text: Model.Text, AutoFocus: true, Part: Model.Part)
</fieldset>

View File

@ -70,6 +70,18 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>

View File

@ -31,22 +31,26 @@ namespace Orchard.Localization.Handlers {
protected static void PropertySetHandlers(ActivatedContentContext context, LocalizationPart localizationPart) {
localizationPart.CultureField.Setter(cultureRecord => {
localizationPart.Record.CultureId = cultureRecord != null ? cultureRecord.Id : 0;
localizationPart.Store<LocalizationPart, LocalizationPartRecord, int>(r => r.CultureId,
cultureRecord != null ? cultureRecord.Id : 0);
return cultureRecord;
});
localizationPart.MasterContentItemField.Setter(masterContentItem => {
localizationPart.Record.MasterContentItemId = masterContentItem.ContentItem.Id;
localizationPart.Store<LocalizationPart, LocalizationPartRecord, int>(r => r.MasterContentItemId,
masterContentItem.ContentItem.Id);
return masterContentItem;
});
}
protected void LazyLoadHandlers(LocalizationPart localizationPart) {
localizationPart.CultureField.Loader(() =>
_cultureManager.GetCultureById(localizationPart.Record.CultureId));
_cultureManager.GetCultureById(
localizationPart.Retrieve<LocalizationPart, LocalizationPartRecord, int>(r => r.CultureId)));
localizationPart.MasterContentItemField.Loader(() =>
_contentManager.Get(localizationPart.Record.MasterContentItemId, VersionOptions.AllVersions));
_contentManager.Get(
localizationPart.Retrieve<LocalizationPart, LocalizationPartRecord, int>(r => r.MasterContentItemId), VersionOptions.AllVersions));
}
}
}

View File

@ -73,16 +73,22 @@ namespace Orchard.MediaLibrary.Drivers {
}
protected override void Importing(ContentPart part, Fields.MediaLibraryPickerField field, ImportContentContext context) {
// If nothing about the field is inside the context, field is not modified.
// For this reason, check if the current element is inside the ImportContentContext.
var element = context.Data.Element(field.FieldDefinition.Name + "." + field.Name);
if (element != null) {
var contentItemIds = context.Attribute(field.FieldDefinition.Name + "." + field.Name, "ContentItems");
if (contentItemIds != null) {
if (!string.IsNullOrWhiteSpace(contentItemIds)) {
field.Ids = contentItemIds.Split(',')
.Select(context.GetItemFromSession)
.Select(contentItem => contentItem.Id).ToArray();
}
else {
} else {
field.Ids = new int[0];
}
}
}
protected override void Exporting(ContentPart part, Fields.MediaLibraryPickerField field, ExportContentContext context) {
if (field.Ids.Any()) {

View File

@ -13,6 +13,11 @@ namespace Orchard.MediaLibrary.Models {
set { this.Store(x => x.UploadAllowedFileTypeWhitelist, value); }
}
public int LimitConcurrentUploads {
get { return this.Retrieve(x => x.LimitConcurrentUploads); }
set { this.Store(x => x.LimitConcurrentUploads, value); }
}
public bool IsFileAllowed(string filename) {
var allowedExtensions = (UploadAllowedFileTypeWhitelist ?? "")

View File

@ -58,6 +58,10 @@
height: 40px;
overflow: hidden;
}
.thumbnail .overlay {
height: 40px;
overflow: hidden;
}
.overlay h3 {
padding-right:5px;

View File

@ -1,4 +1,7 @@
@model Orchard.MediaLibrary.ViewModels.ImportMediaViewModel
@using Orchard.MediaLibrary.Models;
@using Orchard.ContentManagement;
@model Orchard.MediaLibrary.ViewModels.ImportMediaViewModel
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@ -12,6 +15,8 @@
Script.Require("jQueryFileUpload").AtFoot();
Script.Require("Knockout").AtFoot();
var settings = WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
}
@Display.Metas()
@ -23,7 +28,7 @@
<div id="clientstorage-main">
<div id="message">@T("Click here, Drop files or Paste images")</div>
<div id="fileupload">
<input type="file" name="files[]" @if(Model.Replace == null) { <text>multiple="multiple"</text> } >
<input type="file" name="files[]" @if (Model.Replace == null) {<text>multiple="multiple" </text>} />
<ul id="fileupload-transfers" data-bind="foreach: transfers">
<li data-bind="css: status()" class="transfer">
<div class="media-thumbnail" data-bind="html: thumbnail(), visible: status() == 'success'"></div>
@ -80,6 +85,7 @@
// Add drag-n-drop HTML5 support
$('#fileupload').fileupload({
autoUpload: true,
@((settings.LimitConcurrentUploads > 0) ? "limitConcurrentUploads:" + settings.LimitConcurrentUploads + "," : "")
@if(Model.Replace == null) {
<text>
url: '@Url.Action("Upload")',

View File

@ -6,5 +6,8 @@
<label for="@Html.IdFor(m => m.UploadAllowedFileTypeWhitelist)">@T("Accepted file extensions")</label>
@Html.TextBoxFor(m => m.UploadAllowedFileTypeWhitelist, new { @class = "text large"})
<span class="hint">@T("A comma separated list of file extensions, e.g., \".jpg, .avi, .txt\". Leave empty to accept any file types.")</span>
<label for="@Html.IdFor(m => m.LimitConcurrentUploads)">@T("Concurrent uploads limit")</label>
@Html.TextBoxFor(m => m.LimitConcurrentUploads, new { @class = "text medium"})
<span class="hint">@T("To limit the number of concurrent uploads, set this value to an integer greater than 0")</span>
</div>
</fieldset>

View File

@ -1,6 +1,6 @@
@using Orchard.ContentManagement
@using Orchard.Localization.Models;
@using Orchard.Utility.Extensions;
@using Orchard.Localization.Models
@using Orchard.Utility.Extensions
@{
Style.Include("media-library-picker-admin.css");

View File

@ -171,6 +171,8 @@ namespace Orchard.MediaProcessing.Services {
}
}
}
// the storage provider may have altered the filepath
filterContext.FilePath = newFile.GetPath();
}
}
catch(Exception e) {

View File

@ -395,6 +395,9 @@ namespace Orchard.OutputCache.Filters {
// Vary by theme.
result.Add("theme", _workContext.CurrentTheme.Id.ToLowerInvariant());
// Vary for ajax vs "normal" calls
result.Add("isajax", filterContext.HttpContext.Request.IsAjaxRequest().ToString());
// Vary by configured query string parameters.
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
foreach (var key in queryString.AllKeys) {
@ -415,7 +418,7 @@ namespace Orchard.OutputCache.Filters {
// Vary by configured request headers.
var requestHeaders = filterContext.RequestContext.HttpContext.Request.Headers;
foreach (var varyByRequestHeader in CacheSettings.VaryByRequestHeaders) {
if (requestHeaders[varyByRequestHeader]!=null)
if (requestHeaders[varyByRequestHeader] != null)
result["HEADER:" + varyByRequestHeader] = requestHeaders[varyByRequestHeader];
}

View File

@ -1,7 +1,6 @@
using System;
using System.Data;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Common.Models;
using Orchard.Core.Contents.Extensions;
@ -17,11 +16,19 @@ namespace Orchard.Projections {
private readonly IRepository<LayoutRecord> _layoutRepository;
private readonly IRepository<PropertyRecord> _propertyRecordRepository;
/// <summary>
/// When upgrading from "1.10.x" branch code committed after 1.10.3 to "dev" branch code or 1.11, merge
/// conflicts between "1.10.x" and "dev" caused by running the same migration steps in a different order need to
/// be resolved by instructing this migration to decide which steps need to be executed. If you're upgrading
/// under these conditions and your pre-upgrade migration version is 6, use HostComponents.config to override
/// this property to true.
/// </summary>
public bool IsUpgradingFromOrchard_1_10_x_Version_6 { get; set; }
public Migrations(
IRepository<MemberBindingRecord> memberBindingRepository,
IRepository<LayoutRecord> layoutRepository,
IRepository<PropertyRecord> propertyRecordRepository) {
_memberBindingRepository = memberBindingRepository;
_layoutRepository = layoutRepository;
_propertyRecordRepository = propertyRecordRepository;
@ -40,6 +47,7 @@ namespace Orchard.Projections {
.Column<int>("Id", c => c.PrimaryKey().Identity())
.Column<string>("PropertyName")
.Column<string>("Value", c => c.WithLength(4000))
.Column<string>("LatestValue", c => c.WithLength(4000))
.Column<int>("FieldIndexPartRecord_Id")
);
@ -48,6 +56,7 @@ namespace Orchard.Projections {
.Column<int>("Id", c => c.PrimaryKey().Identity())
.Column<string>("PropertyName")
.Column<long>("Value")
.Column<long>("LatestValue")
.Column<int>("FieldIndexPartRecord_Id")
);
@ -56,6 +65,7 @@ namespace Orchard.Projections {
.Column<int>("Id", c => c.PrimaryKey().Identity())
.Column<string>("PropertyName")
.Column<double>("Value")
.Column<double>("LatestValue")
.Column<int>("FieldIndexPartRecord_Id")
);
@ -64,9 +74,28 @@ namespace Orchard.Projections {
.Column<int>("Id", c => c.PrimaryKey().Identity())
.Column<string>("PropertyName")
.Column<decimal>("Value")
.Column<decimal>("LatestValue")
.Column<int>("FieldIndexPartRecord_Id")
);
//Adds indexes for better performances in queries
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_StringFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("IntegerFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_IntegerFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("DoubleFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_DoubleFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_DecimalFieldIndexRecords", "FieldIndexPartRecord_Id");
});
SchemaBuilder.CreateTable("FieldIndexPartRecord", table => table.ContentPartRecord());
// Query
@ -81,6 +110,7 @@ namespace Orchard.Projections {
SchemaBuilder.CreateTable("QueryPartRecord",
table => table
.ContentPartRecord()
.Column<string>("VersionScope", c => c.WithLength(15))
);
SchemaBuilder.CreateTable("FilterGroupRecord",
@ -119,6 +149,7 @@ namespace Orchard.Projections {
.Column<string>("Description", c => c.WithLength(255))
.Column<string>("State", c => c.Unlimited())
.Column<string>("DisplayType", c => c.WithLength(64))
.Column<string>("GUIdentifier", column => column.WithLength(68))
.Column<int>("Display")
.Column<int>("QueryPartRecord_id")
.Column<int>("GroupProperty_id")
@ -154,6 +185,7 @@ namespace Orchard.Projections {
.Column<bool>("HideEmpty")
.Column<bool>("RewriteOutput")
.Column<string>("RewriteOutputCondition", c => c.Unlimited())
.Column<string>("RewriteText", c => c.Unlimited())
.Column<bool>("StripHtmlTags")
.Column<bool>("TrimLength")
@ -252,19 +284,6 @@ namespace Orchard.Projections {
Description = T("The text from the Body part").Text
});
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => table
.CreateIndex("IDX_Orchard_Projections_StringFieldIndexRecord", "FieldIndexPartRecord_Id")
);
SchemaBuilder.AlterTable("IntegerFieldIndexRecord", table => table
.CreateIndex("IDX_Orchard_Projections_IntegerFieldIndexRecord", "FieldIndexPartRecord_Id")
);
SchemaBuilder.AlterTable("DoubleFieldIndexRecord", table => table
.CreateIndex("IDX_Orchard_Projections_DoubleFieldIndexRecord", "FieldIndexPartRecord_Id")
);
SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => table
.CreateIndex("IDX_Orchard_Projections_DecimalFieldIndexRecords", "FieldIndexPartRecord_Id")
);
SchemaBuilder.CreateTable("NavigationQueryPartRecord",
table => table.ContentPartRecord()
.Column<int>("Items")
@ -283,7 +302,7 @@ namespace Orchard.Projections {
.WithIdentity()
);
return 4;
return 7;
}
public int UpdateFrom1() {
@ -306,7 +325,7 @@ namespace Orchard.Projections {
ContentDefinitionManager.AlterTypeDefinition("ProjectionPage", cfg => cfg.Listable());
return 3;
return 2;
}
public int UpdateFrom2() {
@ -340,17 +359,22 @@ namespace Orchard.Projections {
.AddColumn<decimal>("LatestValue"));
//Adds indexes for better performances in queries
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => table.CreateIndex("IX_PropertyName", new string[] { "PropertyName" }));
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => table.CreateIndex("IX_FieldIndexPartRecord_Id", new string[] { "FieldIndexPartRecord_Id" }));
SchemaBuilder.AlterTable("IntegerFieldIndexRecord", table => table.CreateIndex("IX_PropertyName", new string[] { "PropertyName" }));
SchemaBuilder.AlterTable("IntegerFieldIndexRecord", table => table.CreateIndex("IX_FieldIndexPartRecord_Id", new string[] { "FieldIndexPartRecord_Id" }));
SchemaBuilder.AlterTable("DoubleFieldIndexRecord", table => table.CreateIndex("IX_PropertyName", new string[] { "PropertyName" }));
SchemaBuilder.AlterTable("DoubleFieldIndexRecord", table => table.CreateIndex("IX_FieldIndexPartRecord_Id", new string[] { "FieldIndexPartRecord_Id" }));
SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => table.CreateIndex("IX_PropertyName", new string[] { "PropertyName" }));
SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => table.CreateIndex("IX_FieldIndexPartRecord_Id", new string[] { "FieldIndexPartRecord_Id" }));
SchemaBuilder.AlterTable("StringFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_StringFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("IntegerFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_IntegerFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("DoubleFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_DoubleFieldIndexRecord", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => {
table.CreateIndex("IDX_Orchard_Projections_PropertyName", "PropertyName");
table.CreateIndex("IDX_Orchard_Projections_DecimalFieldIndexRecords", "FieldIndexPartRecord_Id");
});
SchemaBuilder.AlterTable("QueryPartRecord", table => table
.AddColumn<string>("VersionScope", c => c.WithLength(15)));
@ -358,32 +382,41 @@ namespace Orchard.Projections {
return 5;
}
#pragma warning disable CS0618
// disable compiler warning regarding the fact that RewriteOutput is obsolete
// because this migration is handling just that.
public int UpdateFrom5() {
SchemaBuilder.AlterTable("PropertyRecord", table => table
.AddColumn<string>("RewriteOutputCondition", c => c.Unlimited())
);
foreach (var property in _propertyRecordRepository.Table)
if (property.RewriteOutput) property.RewriteOutputCondition = "true";
MigratePropertyRecordToRewriteOutputCondition();
return 6;
}
#pragma warning restore CS0618
public int UpdateFrom6() {
SchemaBuilder.AlterTable("LayoutRecord", t => t.AddColumn<string>("GUIdentifier",
column => column.WithLength(68)));
if (IsUpgradingFromOrchard_1_10_x_Version_6) {
MigratePropertyRecordToRewriteOutputCondition();
}
else {
// This change was originally UpdateFrom5 on 1.10.x and UpdateFrom6 on dev.
SchemaBuilder.AlterTable("LayoutRecord", table =>
table.AddColumn<string>("GUIdentifier", column => column.WithLength(68)));
var layoutRecords = _layoutRepository.Table.Where(l => l.GUIdentifier == null || l.GUIdentifier == "").ToList();
foreach (var layout in layoutRecords) {
layout.GUIdentifier = Guid.NewGuid().ToString();
}
}
return 7;
}
// This change was originally in UpdateFrom5 on dev, but didn't exist on 1.10.x.
private void MigratePropertyRecordToRewriteOutputCondition() {
SchemaBuilder.AlterTable("PropertyRecord", table => table
.AddColumn<string>("RewriteOutputCondition", c => c.Unlimited())
);
foreach (var property in _propertyRecordRepository.Table)
#pragma warning disable CS0618 // Type or member is obsolete
// Reading this obsolete property to migrate its data to a new one.
if (property.RewriteOutput) property.RewriteOutputCondition = "true";
#pragma warning restore CS0618 // Type or member is obsolete
}
}
}

View File

@ -62,10 +62,10 @@ namespace Orchard.Projections.Settings {
model.QueryRecordEntries = GetQueriesRecordEntry();
if(updateModel.TryUpdateModel(model, "ProjectionPartSettings", null, null)) {
if (model.FilterQueryRecordsId != null && model.FilterQueryRecordsId.Count()>0) {
if (updateModel.TryUpdateModel(model, "ProjectionPartSettings", null, null)) {
if (model.FilterQueryRecordsId != null && model.FilterQueryRecordsId.Count() > 0) {
// check if default query selected is in filter queries list
if (!model.FilterQueryRecordsId.Contains(model.QueryLayoutRecordId) && model.QueryLayoutRecordId!="-1") {
if (!model.FilterQueryRecordsId.Contains(model.QueryLayoutRecordId) && model.QueryLayoutRecordId != "-1") {
updateModel.AddModelError("ProjectionPart", T("The default query must be one of the selected queries"));
}
@ -149,7 +149,8 @@ namespace Orchard.Projections.Settings {
}
}
settings.FilterQueryRecordId = string.Join("&", identityForFilterQuery);
} else {
}
else {
settings.FilterQueryRecordId = string.Empty;
}

View File

@ -7,3 +7,4 @@ OrchardVersion: 1.10.3
Description: Provides Orchard Recipes.
FeatureDescription: Implementation of Orchard recipes.
Category: Core
Dependencies: PackagingServices

View File

@ -3,6 +3,7 @@ using System.Linq;
using log4net;
using Orchard.Data;
using Orchard.Logging;
using Orchard.Mvc;
using Orchard.Recipes.Events;
using Orchard.Recipes.Models;
@ -12,17 +13,38 @@ namespace Orchard.Recipes.Services {
private readonly IRecipeScheduler _recipeScheduler;
private readonly IRecipeExecuteEventHandler _recipeExecuteEventHandler;
private readonly IRepository<RecipeStepResultRecord> _recipeStepResultRecordRepository;
private readonly IHttpContextAccessor _httpContextAccessor;
public RecipeManager(
IRecipeStepQueue recipeStepQueue,
IRecipeScheduler recipeScheduler,
IRecipeExecuteEventHandler recipeExecuteEventHandler,
IRepository<RecipeStepResultRecord> recipeStepResultRecordRepository) {
IRepository<RecipeStepResultRecord> recipeStepResultRecordRepository,
IHttpContextAccessor httpContextAccessor) {
_recipeStepQueue = recipeStepQueue;
_recipeScheduler = recipeScheduler;
_recipeExecuteEventHandler = recipeExecuteEventHandler;
_recipeStepResultRecordRepository = recipeStepResultRecordRepository;
_httpContextAccessor = httpContextAccessor;
RecipeExecutionTimeout = 600;
}
public int RecipeExecutionTimeout {
get; set;
// The public setter allows injecting this from Sites.MyTenant.Config or Sites.config, by using
// an AutoFac component:
/*
<component instance-scope="per-lifetime-scope"
type="Orchard.Recipes.Services.RecipeManager, Orchard.Recipes.Services"
service="Orchard.Recipes.Services.RecipeManager">
<properties>
<property name="RecipeExecutionTimeout" value="600" />
</properties>
</component>
*/
}
public string Execute(Recipe recipe) {
@ -35,6 +57,12 @@ namespace Orchard.Recipes.Services {
return null;
}
// Sets the request timeout to a configurable amount of seconds to give enough time to execute custom recipes.
var httpContext = _httpContextAccessor.Current();
if (httpContext != null) {
httpContext.Server.ScriptTimeout = RecipeExecutionTimeout;
}
var executionId = Guid.NewGuid().ToString("n");
ThreadContext.Properties["ExecutionId"] = executionId;

View File

@ -0,0 +1,56 @@
using System.Collections.Generic;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;
namespace Orchard.Roles.Activities {
[OrchardFeature("Orchard.Roles.Workflows")]
public class RoleEventActivity : Event {
public Localizer T { get; set; }
public RoleEventActivity() {
T = NullLocalizer.Instance;
}
public override bool CanStartWorkflow {
get { return true; }
}
public override string Name {
get {
return "OnRoleEvent";
}
}
public override LocalizedString Category {
get {
return T("Roles");
}
}
public override LocalizedString Description {
get {
return T("Manage Role Event");
}
}
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
string operatore = workflowContext.Tokens["Action"].ToString();
LocalizedString msg = T(operatore);
yield return msg;
}
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return new[] {
T("Created"),
T("Removed"),
T("Renamed"),
T("UserAdded"),
T("UserRemoved"),
T("PermissionAdded"),
T("PermissionRemoved")
};
}
}
}

View File

@ -0,0 +1,79 @@
using System.Collections.Generic;
using Orchard.Environment.Extensions;
using Orchard.Workflows.Services;
namespace Orchard.Roles.Events {
[OrchardFeature("Orchard.Roles.Workflows")]
public class RoleEventHandler : IRoleEventHandler {
private readonly IWorkflowManager _workflowManager;
public RoleEventHandler(IWorkflowManager workflowManager) {
_workflowManager = workflowManager;
}
public void Created(RoleCreatedContext context) {
_workflowManager.TriggerEvent("OnRoleEvent",
null,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "Action", "Created" } });
}
public void PermissionAdded(PermissionAddedContext context) {
_workflowManager.TriggerEvent("OnRoleEvent",
null,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "Permission", context.Permission },
{ "Action", "PermissionAdded" } });
}
public void PermissionRemoved(PermissionRemovedContext context) {
_workflowManager.TriggerEvent("OnRoleEvent",
null,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "Permission", context.Permission },
{ "Action", "PermissionRemoved" } });
}
public void Removed(RoleRemovedContext context) {
_workflowManager.TriggerEvent("OnRoleEvent",
null,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "Action", "Removed" } });
}
public void Renamed(RoleRenamedContext context) {
_workflowManager.TriggerEvent("OnRoleEvent",
null,
() => new Dictionary<string, object> {
{ "PreviousName", context.PreviousRoleName },
{ "NewName", context.NewRoleName },
{ "Action", "Renamed" } });
}
public void UserAdded(UserAddedContext context) {
// Content of workflow event is the user
var content = context.User.ContentItem;
_workflowManager.TriggerEvent("OnRoleEvent",
content,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "User", context.User },
{ "Action", "UserAdded" } });
}
public void UserRemoved(UserRemovedContext context) {
// Content of workflow event is the user
var content = context.User.ContentItem;
_workflowManager.TriggerEvent("OnRoleEvent",
content,
() => new Dictionary<string, object> {
{ "Role", context.Role },
{ "User", context.User },
{ "Action", "UserRemoved" } });
}
}
}

View File

@ -95,6 +95,7 @@
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="Activities\RoleEventActivity.cs" />
<Compile Include="Activities\UnassignRoleActivity.cs" />
<Compile Include="Activities\AssignRoleActivity.cs" />
<Compile Include="Activities\IsInRoleActivity.cs" />
@ -111,6 +112,7 @@
<Compile Include="Events\PermissionRoleContext.cs" />
<Compile Include="Events\RoleContext.cs" />
<Compile Include="Events\RoleCreatedContext.cs" />
<Compile Include="Events\RoleEventHandler.cs" />
<Compile Include="Events\RoleRemovedContext.cs" />
<Compile Include="Events\RoleRenamedContext.cs" />
<Compile Include="Events\UserAddedContext.cs" />

View File

@ -29,6 +29,7 @@
<compilation targetFramework="4.8">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />

View File

@ -0,0 +1,42 @@
using System.Linq;
using Orchard.Blogs;
using Orchard.Blogs.Services;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Security;
using Orchard.UI.Navigation;
namespace Orchard.Search {
[OrchardFeature("Orchard.Search.Blogs")]
public class BlogPostsLocalNavigationProvider : INavigationProvider {
private readonly IBlogService _blogService;
private readonly IAuthorizationService _authorizationService;
private readonly IWorkContextAccessor _workContextAccessor;
public BlogPostsLocalNavigationProvider(
IBlogService blogService,
IAuthorizationService authorizationService,
IWorkContextAccessor workContextAccessor) {
T = NullLocalizer.Instance;
_blogService = blogService;
_authorizationService = authorizationService;
_workContextAccessor = workContextAccessor;
}
public Localizer T { get; set; }
public string MenuName {
get { return "blogposts-navigation"; }
}
public void GetNavigation(NavigationBuilder builder) {
var blogId = 0;
int.TryParse(_workContextAccessor.GetContext().HttpContext.Request.RequestContext.RouteData.Values["blogId"]?.ToString(), out blogId);
if (blogId > 0) {
builder.Add(T("Search Posts"), "2.0", item => item.Action("Index", "BlogSearch", new { area = "Orchard.Search", blogId })
.LocalNav()
.Permission(Permissions.MetaListOwnBlogs));
}
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Environment.Extensions;
namespace Orchard.Search {
[OrchardFeature("Orchard.Search.Blogs")]
public class BlogSearchConstants {
public static string ADMIN_BLOGPOSTS_INDEX = "AdminBlogPosts";
}
}

View File

@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.Collections;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.DisplayManagement;
using Orchard.Environment.Extensions;
using Orchard.Indexing;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Logging;
using Orchard.Search.Helpers;
using Orchard.Search.Models;
using Orchard.Search.Services;
using Orchard.Security;
using Orchard.Settings;
using Orchard.UI.Admin;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
namespace Orchard.Search.Controllers {
[OrchardFeature("Orchard.Search.Blogs")]
[Admin]
public class BlogSearchController : Controller {
private readonly ISearchService _searchService;
private readonly ISiteService _siteService;
private readonly IIndexManager _indexManager;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IContentManager _contentManager;
private readonly IAuthorizer _authorizer;
private readonly ICultureManager _cultureManager;
private readonly INavigationManager _navigationManager;
public BlogSearchController(
IOrchardServices orchardServices,
ISearchService searchService,
ISiteService siteService,
IIndexManager indexManager,
IContentDefinitionManager contentDefinitionManager,
IContentManager contentManager,
IAuthorizer authorizer,
ICultureManager cultureManager,
INavigationManager navigationManager,
IShapeFactory shapeFactory) {
_searchService = searchService;
_siteService = siteService;
Services = orchardServices;
_indexManager = indexManager;
_contentDefinitionManager = contentDefinitionManager;
_contentManager = contentManager;
_authorizer = authorizer;
_cultureManager = cultureManager;
_navigationManager = navigationManager;
Shape = shapeFactory;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
}
public IOrchardServices Services { get; set; }
public ILogger Logger { get; set; }
public Localizer T { get; set; }
public dynamic Shape { get; set; }
public ActionResult Index(int blogId, PagerParameters pagerParameters, string searchText = "") {
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var searchSettingsPart = Services.WorkContext.CurrentSite.As<SearchSettingsPart>();
IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { });
try {
if (!string.IsNullOrWhiteSpace(searchText)) {
var searchableTypes = new List<string>();
// add the type to the list of types we will filter for
// BlogPost for now but we would add more types in the future (i.e. "Article")
searchableTypes.Add("BlogPost");
var searchBuilder = _indexManager.HasIndexProvider()
? _indexManager
.GetSearchIndexProvider()
.CreateSearchBuilder(BlogSearchConstants.ADMIN_BLOGPOSTS_INDEX)
: new NullSearchBuilder();
searchBuilder
.Parse(searchSettingsPart
.GetSearchFields(BlogSearchConstants.ADMIN_BLOGPOSTS_INDEX),
searchText);
// filter by Blog
searchBuilder
.WithField("container-id", blogId)
.Mandatory()
.NotAnalyzed()
.AsFilter();
foreach (var searchableType in searchableTypes) {
// filter by type
searchBuilder
.WithField("type", searchableType)
.NotAnalyzed()
.AsFilter();
}
// pagination
var totalCount = searchBuilder.Count();
if (pager != null) {
searchBuilder = searchBuilder
.Slice(
(pager.Page > 0 ? pager.Page - 1 : 0) * pager.PageSize,
pager.PageSize);
}
// search
var searchResults = searchBuilder.Search();
// prepare the shape for the page
searchHits = new PageOfItems<ISearchHit>(searchResults.Select(searchHit => searchHit)) {
PageNumber = pager != null ? pager.Page : 0,
PageSize = pager != null ? (pager.PageSize != 0 ? pager.PageSize : totalCount) : totalCount,
TotalItemCount = totalCount
};
}
}
catch (Exception exception) {
Logger.Error(T("Invalid search query: {0}", exception.Message).Text);
Services.Notifier.Error(T("Invalid search query: {0}", exception.Message));
}
var list = Services.New.List();
foreach (var contentItem in Services.ContentManager.GetMany<IContent>(searchHits.Select(x => x.ContentItemId), VersionOptions.Latest, QueryHints.Empty)) {
// ignore search results which content item has been removed
if (contentItem == null) {
searchHits.TotalItemCount--;
continue;
}
list.Add(Services.ContentManager.BuildDisplay(contentItem, "SummaryAdmin"));
}
var pagerShape = Services.New.Pager(pager).TotalItemCount(searchHits.TotalItemCount);
var viewModel = Services.New.ViewModel()
.ContentItems(list)
.Pager(pagerShape)
.SearchText(searchText)
.BlogId(blogId);
// Adds LocalMenus;
var menuItems = _navigationManager.BuildMenu("blogposts-navigation");
var request = Services.WorkContext.HttpContext.Request;
// Set the currently selected path
Stack<MenuItem> selectedPath = NavigationHelper.SetSelectedPath(menuItems, request, request.RequestContext.RouteData);
// Populate local nav
dynamic localMenuShape = Shape.LocalMenu().MenuName("local-admin");
NavigationHelper.PopulateLocalMenu(Shape, localMenuShape, localMenuShape, menuItems);
Services.WorkContext.Layout.LocalNavigation.Add(localMenuShape);
return View(viewModel);
}
}
}

View File

@ -69,4 +69,23 @@ namespace Orchard.Search {
return 1;
}
}
[OrchardFeature("Orchard.Search.Blogs")]
public class BlogsMigration : DataMigrationImpl {
private readonly IIndexManager _indexManager;
public BlogsMigration(IIndexManager indexManager) {
_indexManager = indexManager;
}
public int Create() {
_indexManager.GetSearchIndexProvider().CreateIndex(BlogSearchConstants.ADMIN_BLOGPOSTS_INDEX);
ContentDefinitionManager.AlterTypeDefinition("BlogPost", cfg => cfg.WithSetting("TypeIndexing.Indexes", BlogSearchConstants.ADMIN_BLOGPOSTS_INDEX + ":latest"));
return 1;
}
}
}

View File

@ -27,3 +27,8 @@ Features:
Description: Provides search menu item in the Media Library explorer.
Dependencies: Orchard.MediaLibrary, Orchard.Search
Category: Search
Orchard.Search.Blogs:
Name: Blog posts Search
Description: Provides search menu item in the Blog section.
Dependencies: Orchard.Blogs, Orchard.Search
Category: Search

View File

@ -93,7 +93,10 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Commands\SearchCommands.cs" />
<Compile Include="BlogPostsLocalNavigationProvider.cs" />
<Compile Include="Constants.cs" />
<Compile Include="ContentPickerNavigationProvider.cs" />
<Compile Include="Controllers\BlogSearchController.cs" />
<Compile Include="Controllers\ContentPickerController.cs" />
<Compile Include="ContentAdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
@ -134,6 +137,10 @@
<Name>Orchard.Core</Name>
<Private>$(MvcBuildViews)</Private>
</ProjectReference>
<ProjectReference Include="..\Orchard.Blogs\Orchard.Blogs.csproj">
<Project>{63FBD4D9-E1DA-4A7B-AA6A-D6074FE50867}</Project>
<Name>Orchard.Blogs</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.MediaLibrary\Orchard.MediaLibrary.csproj">
<Project>{73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b}</Project>
<Name>Orchard.MediaLibrary</Name>
@ -207,6 +214,7 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<Content Include="Views\BlogSearch\Index.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>

View File

@ -36,6 +36,21 @@ namespace Orchard.Search {
{"area", "Orchard.Search"}
},
new MvcRouteHandler())
},
new RouteDescriptor {
Priority = 5,
Route = new Route("Admin/Search/BlogSearch/{blogId}",
new RouteValueDictionary {
{"area", "Orchard.Search"},
{"controller", "BlogSearch"},
{"action", "Index"},
{"blogId", UrlParameter.Optional}
},
null,
new RouteValueDictionary {
{"area", "Orchard.Search"}
},
new MvcRouteHandler())
}
};

View File

@ -0,0 +1,21 @@
@{
var pageTitle = T("Search Content");
Layout.Title = pageTitle;
}
@using (Html.BeginFormAntiForgeryPost(Url.Action("index", new { controller = "BlogSearch", area = "Orchard.Search", blogId = Model.BlogId }), FormMethod.Get)) {
<label for="search-text">@T("Search")</label>
@Html.TextBox("searchText", (string)Model.SearchText, new { @class = "text medium", autofocus = "autofocus" })
<button type="submit">@T("Search")</button>
<fieldset class="contentItems bulk-items">
@Display(Model.ContentItems)
</fieldset>
if (HasText(Model.SearchText) && Model.ContentItems.Items.Count == 0) {
@T("There are no results")
}
@Display(Model.Pager)
}

View File

@ -52,7 +52,11 @@ namespace Orchard.Taxonomies.Drivers {
var pagerParameters = new PagerParameters();
var httpContext = _httpContextAccessor.Current();
if (httpContext != null) {
pagerParameters.Page = Convert.ToInt32(httpContext.Request.QueryString["page"]);
// Check if "page" parameter is a valid number.
int page = 0;
if (int.TryParse(httpContext.Request.QueryString["page"], out page)) {
pagerParameters.Page = page;
}
}
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);

View File

@ -22,8 +22,16 @@ namespace Orchard.Taxonomies.Navigation {
ITaxonomyService taxonomyService) {
_contentManager = contentManager;
_taxonomyService = taxonomyService;
_termsMemory = new Dictionary<string, TermPart[]>();
}
// Prevent doing the same query for terms more than once on a same request
// in case we are building menus from the same starting taxonomies. Key is a
// string to "combine" the Id of the root TermPart and the flag telling to
// add that root to the results.
private Dictionary<string, TermPart[]> _termsMemory;
public IEnumerable<MenuItem> Filter(IEnumerable<MenuItem> items) {
foreach (var item in items) {
@ -34,14 +42,21 @@ namespace Orchard.Taxonomies.Navigation {
var rootTerm = _taxonomyService.GetTerm(taxonomyNavigationPart.TermId);
TermPart[] allTerms;
string memoryKey;
if (rootTerm != null) {
memoryKey = $"{rootTerm.Id}_{taxonomyNavigationPart.DisplayRootTerm}";
if (!_termsMemory.ContainsKey(memoryKey)) {
// if DisplayRootTerm is specified add it to the menu items to render
allTerms = _taxonomyService.GetChildren(rootTerm, taxonomyNavigationPart.DisplayRootTerm).ToArray();
_termsMemory[memoryKey] = _taxonomyService.GetChildren(rootTerm, taxonomyNavigationPart.DisplayRootTerm).ToArray();
}
}
else {
allTerms = _taxonomyService.GetTerms(taxonomyNavigationPart.TaxonomyId).ToArray();
memoryKey = taxonomyNavigationPart.TaxonomyId.ToString();
if (!_termsMemory.ContainsKey(memoryKey)) {
_termsMemory[memoryKey] = _taxonomyService.GetTerms(taxonomyNavigationPart.TaxonomyId).ToArray();
}
}
allTerms = _termsMemory[memoryKey];
var rootLevel = rootTerm != null
? rootTerm.GetLevels()

View File

@ -87,7 +87,6 @@
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>

View File

@ -11,6 +11,8 @@
int termIndex = 0;
var settings = Model.Settings;
var noSelectionId = Guid.NewGuid();
}
<fieldset class="taxonomy-wrapper" data-name-prefix="@Html.FieldNameFor(m => m)" data-id-prefix="@Html.FieldIdFor(m => m)">
@ -22,16 +24,21 @@
}
<ul class="terms">
@if (Model.Settings.SingleChoice && !settings.Required) {
<li>
<input type="radio" value="0" @if (Model.SingleTermId == 0) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.SingleTermId)" id="@noSelectionId" data-term="@T("No selection")" />
<label class="forcheckbox" for="@noSelectionId">@T("No selection")</label>
</li>
}
@foreach (var entry in Model.Terms) {
var ti = termIndex;
<li>
@* Tabs for levels *@ @for (var i = 1; i <= entry.GetLevels(); i++) { <span class="gap">&nbsp;</span> }
@* Tabs for levels *@ @for (var i = 1; i <= entry.GetLevels(); i++) {<span class="gap">&nbsp;</span>}
@{
var disabled = !entry.Selectable || (Model.Settings.LeavesOnly && Model.Terms.Any(t => t.Path.Contains(entry.Path + entry.Id)));
if (Model.Settings.SingleChoice) {
<input @if (disabled) { <text> disabled="disabled" </text> } type="radio" value="@Model.Terms[ti].Id" @if (entry.Id == Model.SingleTermId) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.SingleTermId)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name.ToLower()" />
}
else {
} else {
<input @if (disabled) { <text> disabled="disabled" </text> } type="checkbox" value="true" @if (entry.IsChecked) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.Terms[ti].IsChecked)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name.ToLower()" />
}
}

View File

@ -68,6 +68,18 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>

View File

@ -26,6 +26,9 @@ namespace Orchard.Tokens.Providers {
public Localizer T { get; set; }
public void Describe(DescribeContext context) {
context.For("ContentItem", T("Content Items"), T("The context to access specific content items."))
.Token("Id:*", T("Content Item by Id"), T("The content item with the specified id."));
context.For("Content", T("Content Items"), T("Content Items"))
.Token("Id", T("Content Id"), T("Numeric primary key value of content."))
.Token("Author", T("Content Author"), T("Person in charge of the content."), "User")
@ -36,8 +39,7 @@ namespace Orchard.Tokens.Providers {
.Token("DisplayUrl", T("Display Url"), T("Url to display the content."), "Url")
.Token("EditUrl", T("Edit Url"), T("Url to edit the content."), "Url")
.Token("Container", T("Container"), T("The container Content Item."), "Content")
.Token("Body", T("Body"), T("The body text of the content item."), "Text")
;
.Token("Body", T("Body"), T("The body text of the content item."), "Text");
// Token descriptors for fields
foreach (var typeDefinition in _contentManager.GetContentTypeDefinitions()) {
@ -72,6 +74,38 @@ namespace Orchard.Tokens.Providers {
}
public void Evaluate(EvaluateContext context) {
context.For<IContentManager>("ContentItem", _contentManager)
.Token(
token => token.StartsWith("Id:", StringComparison.OrdinalIgnoreCase) ? ContentManagerGetToken(token) : "",
(token, cm) => {
// token is Id:*
if (token != "") {
var id = token.Substring("Id:".Length);
return cm.Get(Convert.ToInt32(id));
}
else { return null; }
})
.Chain(
token => {
var cleanToken = ContentManagerGetToken(token); // is Id:*
if (string.IsNullOrWhiteSpace(cleanToken)) return null;
int cleanTokenLength = cleanToken.Length;
var subTokens = token.Length > cleanTokenLength ? token.Substring(cleanToken.Length + 1) : "";
return new Tuple<string, string>(
cleanToken, //The specific Token Id:*, it is the key
subTokens //The subsequent Tokens (i.e Fields.PartName.FieldName)
);
},
"Content",
(token, cm) => {
// token is Id:*
if (token != "") {
var id = token.Substring("Id:".Length);
return cm.Get(Convert.ToInt32(id));
}
else { return null; }
});
context.For<IContent>("Content")
.Token("Id", content => content != null ? content.Id : 0)
.Token("Author", AuthorName)
@ -90,8 +124,7 @@ namespace Orchard.Tokens.Providers {
.Token("Container", content => DisplayText(Container(content)))
.Chain("Container", "Content", Container)
.Token("Body", Body)
.Chain("Body", "Text", Body)
;
.Chain("Body", "Text", Body);
if (context.Target == "Content") {
var forContent = context.For<IContent>("Content");
@ -201,5 +234,36 @@ namespace Orchard.Tokens.Providers {
return bodyPart.Text;
}
//returns Id:* Token
private static string ContentManagerGetToken(string token) {
string tokenPrefix, result;
int chainIndex, tokenLength;
if (token.IndexOf(":") == -1) {
return null;
}
tokenPrefix = token.Substring(0, token.IndexOf(":"));
chainIndex = token.IndexOf(".");
tokenLength = (tokenPrefix + ":").Length;
if (!token.StartsWith((tokenPrefix + ":"), StringComparison.OrdinalIgnoreCase) || chainIndex <= tokenLength) {
return null;
}
else if (chainIndex == 0) {// "." has not be found
result = token.Substring(tokenLength);
}
else {
result = token.Substring(0, chainIndex);
}
// return the resulting id if it is a number, otherwise an empty string
if (int.TryParse(result.Substring(tokenPrefix.Length + 1), out var contentid)) {
return result;
}
else {
return "";
}
}
}
}

View File

@ -2,6 +2,7 @@
using Orchard.Data;
using Orchard.ContentManagement.Handlers;
using Orchard.Users.Models;
using System.Web.Routing;
namespace Orchard.Users.Handlers {
public class UserPartHandler : ContentHandler {
@ -16,6 +17,19 @@ namespace Orchard.Users.Handlers {
if (part != null) {
context.Metadata.Identity.Add("User.UserName", part.UserName);
context.Metadata.DisplayText = part.UserName;
// Configure routing metadata to make back-office experience more robust
context.Metadata.CreateRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Users"},
{"Controller", "Admin"},
{"Action", "Create"}
};
context.Metadata.EditorRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Users"},
{"Controller", "Admin"},
{"Action", "Edit"},
{"id", context.ContentItem.Id}
};
}
}
}

View File

@ -128,6 +128,10 @@ namespace Orchard.Users.Services {
if (user == null)
return null;
if (user.As<UserPart>().EmailStatus == UserStatus.Approved) {
return null;
}
user.As<UserPart>().EmailStatus = UserStatus.Approved;
return user;

View File

@ -29,6 +29,7 @@
<compilation targetFramework="4.8">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />

View File

@ -13,6 +13,7 @@ using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Models;
using Orchard.Mvc.Html;
using Orchard.Security;
using Orchard.Widgets.Layouts.Elements;
@ -47,11 +48,30 @@ namespace Orchard.Widgets.Layouts.Providers {
Importing = ImportElement,
StateBag = new Dictionary<string, object> {
{ "ContentTypeName", contentTypeDefinition.Name }
}
},
LayoutSaving = LayoutSaving
};
});
}
private void LayoutSaving(ElementSavingContext context) {
// First, widget element container has to be stored.
var element = (Widget)context.Element;
if (element == null) {
return;
}
var widgetId = element.WidgetId;
var widget = _contentManager.Value.Get(widgetId.Value, VersionOptions.Latest);
if (widget == null) {
return;
}
var commonPart = widget.As<ICommonPart>();
if (commonPart != null) {
commonPart.Container = context.Content;
}
}
private void Displaying(ElementDisplayingContext context) {
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
var element = (Widget)context.Element;
@ -166,6 +186,18 @@ namespace Orchard.Widgets.Layouts.Providers {
return;
var widget = context.Session.GetItemFromSession(widgetIdentity);
// A new widget needs to be created and saved.
// This is to avoid the fact the very same element ending up in multiple layouts, causing issues when e.g. deleting a LayoutWidget of a cloned ContentItem (which would delete the elements of multiple layouts).
// The new widget is needed only when the container of the original element is different from the container of the cloned element, to ensure doing it when cloning elements and avoid doing the same when importing content.
var cp = widget.As<ICommonPart>();
if (cp != null) {
var lp = cp.Container.As<LayoutPart>();
if (lp != null && lp.Id != context.Layout.Id) {
widget = _contentManager.Value.Clone(widget);
}
}
var element = (Widget)context.Element;
element.WidgetId = widget != null ? widget.Id : default(int?);

View File

@ -1,8 +1,8 @@
@using Orchard.ContentManagement;
@using Orchard.Core.Contents;
@using Orchard.Utility.Extensions;
@using Orchard.Widgets.Models;
@using Orchard.Localization.Models;
@using Orchard.ContentManagement
@using Orchard.Core.Contents
@using Orchard.Utility.Extensions
@using Orchard.Widgets.Models
@using Orchard.Localization.Models
@{
Style.Require("WidgetsAdmin");
IEnumerable<WidgetPart> widgets = Model.Widgets;

View File

@ -70,7 +70,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />

View File

@ -29,6 +29,7 @@
<compilation targetFramework="4.8">
<assemblies>
<add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<add assembly="System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />

View File

@ -1,4 +1,6 @@
var mediaPlugins = "";
var contentPickerPlugins = "";
var contentPickerButtons = "";
if (mediaPickerEnabled) {
mediaPlugins += " mediapicker";
@ -8,14 +10,19 @@ if (mediaLibraryEnabled) {
mediaPlugins += " medialibrary";
}
if (contenPickerEnabled && tokensHtmlFilterEnabled) {
contentPickerPlugins += " orchardcontentlinks"
contentPickerButtons += "orchardlink"
}
tinyMCE.init({
selector: "textarea.tinymce",
theme: "modern",
schema: "html5",
plugins: [
"advlist, anchor, autolink, autoresize, charmap, code, colorpicker, contextmenu, directionality, emoticons, fullscreen, hr, image, insertdatetime, link, lists, media, nonbreaking, pagebreak, paste, preview, print, searchreplace, table, template, textcolor, textpattern, visualblocks, visualchars, wordcount" + mediaPlugins
"advlist, anchor, autolink, autoresize, charmap, code, colorpicker, contextmenu, directionality, emoticons, fullscreen, hr, image, insertdatetime, link, lists, media, nonbreaking, pagebreak, paste, preview, print, searchreplace, table, template, textcolor, textpattern, visualblocks, visualchars, wordcount, htmlsnippets" + (contentPickerPlugins != "" ? ", " + contentPickerPlugins : "") + (mediaPlugins != "" ? ", " + mediaPlugins : "")
],
toolbar: "undo redo cut copy paste | bold italic | bullist numlist outdent indent formatselect | alignleft aligncenter alignright alignjustify ltr rtl | " + mediaPlugins + " link unlink charmap | code fullscreen",
toolbar: "undo redo cut copy paste | bold italic | bullist numlist outdent indent formatselect | alignleft aligncenter alignright alignjustify ltr rtl | " + mediaPlugins + " link " + contentPickerButtons + " unlink charmap | code htmlsnippetsbutton fullscreen",
convert_urls: false,
valid_elements: "*[*]",
// Shouldn't be needed due to the valid_elements setting, but TinyMCE would strip script.src without it.
@ -27,7 +34,7 @@ tinyMCE.init({
auto_focus: autofocus,
directionality: directionality,
setup: function (editor) {
$(document).bind("localization.ui.directionalitychanged", function(event, directionality) {
$(document).bind("localization.ui.directionalitychanged", function (event, directionality) {
editor.getBody().dir = directionality;
});

View File

@ -0,0 +1,42 @@

tinymce.PluginManager.add('htmlsnippets', function(editor, url) {
var htmlSnippetAction = function() {
// Open window
var modalWindow = editor.windowManager.open({
title: 'Insert/edit HTML snippets',
body: [
{type: 'textbox', value: editor.selection.getContent(), multiline: true, name: 'html_snippet', label: 'HTML Snippet', minHeight:350}
],
height: 400,
width: 600,
onsubmit: function(e) {
// Insert content when the window form is submitted
editor.insertContent(e.data.html_snippet);
}
});
}
// Add a button that opens a window
editor.addButton('htmlsnippetsbutton', {
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QAEABHAPK/xSSIAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAvElEQVRIx+2VsRHCMAxFH3AwAR075CjSpGOfLEU6nAKmoIICJohHYANoVPjAji0nNLn8OxeSvny2vmTDDCUOQOfYb1mptpU9grDKDX12N20Nvq88OH+ZkLQGDFA7vho4SWwQdkADPIHS8ZfiOwonC1s5+R2oPPFKYka46hpegCtQ9PD3wA0452qwiXBWwlnklqhNKFGrKVFI5EdA5EYrsm8OQm1qPG0anaPRB216eI3wXNvYh2P/+eHM+MEHpr9Js1lOQvUAAAAASUVORK5CYII=',
tooltip: 'Html snippet',
onclick: htmlSnippetAction
});
// Adds a menu item to the tools menu
editor.addMenuItem('HTMLsnippetmenuitem ', {
text: 'Html snippet',
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QAEABHAPK/xSSIAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAvElEQVRIx+2VsRHCMAxFH3AwAR075CjSpGOfLEU6nAKmoIICJohHYANoVPjAji0nNLn8OxeSvny2vmTDDCUOQOfYb1mptpU9grDKDX12N20Nvq88OH+ZkLQGDFA7vho4SWwQdkADPIHS8ZfiOwonC1s5+R2oPPFKYka46hpegCtQ9PD3wA0452qwiXBWwlnklqhNKFGrKVFI5EdA5EYrsm8OQm1qPG0anaPRB216eI3wXNvYh2P/+eHM+MEHpr9Js1lOQvUAAAAASUVORK5CYII=',
context: 'insert',
onclick: htmlSnippetAction
});
return {
getMetadata: function () {
return {
name: "Html snippets plugin"
//url: "http://exampleplugindocsurl.com"
};
}
};
});

View File

@ -0,0 +1 @@
tinymce.PluginManager.add("htmlsnippets",function(A,t){var n=function(){A.windowManager.open({title:"Insert/edit HTML snippets",body:[{type:"textbox",value:A.selection.getContent(),multiline:!0,name:"html_snippet",label:"HTML Snippet",minHeight:350}],height:400,width:600,onsubmit:function(t){A.insertContent(t.data.html_snippet)}})};return A.addButton("htmlsnippetsbutton",{image:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QAEABHAPK/xSSIAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAvElEQVRIx+2VsRHCMAxFH3AwAR075CjSpGOfLEU6nAKmoIICJohHYANoVPjAji0nNLn8OxeSvny2vmTDDCUOQOfYb1mptpU9grDKDX12N20Nvq88OH+ZkLQGDFA7vho4SWwQdkADPIHS8ZfiOwonC1s5+R2oPPFKYka46hpegCtQ9PD3wA0452qwiXBWwlnklqhNKFGrKVFI5EdA5EYrsm8OQm1qPG0anaPRB216eI3wXNvYh2P/+eHM+MEHpr9Js1lOQvUAAAAASUVORK5CYII=",tooltip:"Html snippet",onclick:n}),A.addMenuItem("HTMLsnippetmenuitem ",{text:"Html snippet",image:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QAEABHAPK/xSSIAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAvElEQVRIx+2VsRHCMAxFH3AwAR075CjSpGOfLEU6nAKmoIICJohHYANoVPjAji0nNLn8OxeSvny2vmTDDCUOQOfYb1mptpU9grDKDX12N20Nvq88OH+ZkLQGDFA7vho4SWwQdkADPIHS8ZfiOwonC1s5+R2oPPFKYka46hpegCtQ9PD3wA0452qwiXBWwlnklqhNKFGrKVFI5EdA5EYrsm8OQm1qPG0anaPRB216eI3wXNvYh2P/+eHM+MEHpr9Js1lOQvUAAAAASUVORK5CYII=",context:"insert",onclick:n}),{getMetadata:function(){return{name:"Html snippets plugin"}}}});

View File

@ -17,9 +17,7 @@
// Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceMediaPicker');
ed.addCommand('mceMediaLibrary', function () {
ed.focus();
var adminIndex = location.href.toLowerCase().indexOf("/admin/");
if (adminIndex === -1) return;
var url = location.href.substr(0, adminIndex) + "/Admin/Orchard.MediaLibrary?dialog=true";
var url = baseOrchardPath + "Admin/Orchard.MediaLibrary?dialog=true";
$.colorbox({
href: url,
iframe: true,
@ -41,7 +39,7 @@
var newContent = '';
for (var i = 0; i < selectedData.length; i++) {
var renderMedia = location.href.substr(0, adminIndex) + "/Admin/Orchard.MediaLibrary/MediaItem/" + selectedData[i].id + "?displayType=Raw";
var renderMedia = baseOrchardPath + "/Admin/Orchard.MediaLibrary/MediaItem/" + selectedData[i].id + "?displayType=Raw";
$.ajax({
async: false,
type: 'GET',

View File

@ -1,4 +1 @@
(function(){tinymce.create("tinymce.plugins.Orchard.MediaLibrary",{init:function(n){n.addCommand("mceMediaLibrary",function(){var t,i;(n.focus(),t=location.href.toLowerCase().indexOf("/admin/"),t!==-1)&&(i=location.href.substr(0,t)+"/Admin/Orchard.MediaLibrary?dialog=true",$.colorbox({href:i,iframe:!0,reposition:!0,width:"90%",height:"90%",onLoad:function(){$("html, body").css("overflow","hidden")},onClosed:function(){var n,r,i,u;if($("html, body").css("overflow",""),n=$.colorbox.selectedData,n!=null){for(r="",i=0;i<n.length;i++)u=location.href.substr(0,t)+"/Admin/Orchard.MediaLibrary/MediaItem/"+n[i].id+"?displayType=Raw",$.ajax({async:!1,type:"GET",url:u,success:function(n){r+=n}});tinyMCE.execCommand("mceReplaceContent",!1,r)}}}))});n.addButton("medialibrary",{icon:"image",title:"Insert media",cmd:"mceMediaLibrary"})},createControl:function(){return null},getInfo:function(){return{longname:"Orchard Media Library Plugin",author:"The Orchard Team",authorurl:"http://orchardproject.net",infourl:"http://orchardproject.net",version:"1.1"}}});tinymce.PluginManager.add("medialibrary",tinymce.plugins.Orchard.MediaLibrary)})();
/*
//# sourceMappingURL=plugin.min.js.map
*/
tinymce.create("tinymce.plugins.Orchard.MediaLibrary",{init:function(ed,url){ed.addCommand("mceMediaLibrary",(function(){ed.focus();var url=baseOrchardPath+"Admin/Orchard.MediaLibrary?dialog=true";$.colorbox({href:url,iframe:!0,reposition:!0,width:"90%",height:"90%",onLoad:function(){$("html, body").css("overflow","hidden")},onClosed:function(){$("html, body").css("overflow","");var selectedData=$.colorbox.selectedData;if(null!=selectedData){for(var newContent="",i=0;i<selectedData.length;i++){var renderMedia=baseOrchardPath+"/Admin/Orchard.MediaLibrary/MediaItem/"+selectedData[i].id+"?displayType=Raw";$.ajax({async:!1,type:"GET",url:renderMedia,success:function(data){newContent+=data}})}tinyMCE.execCommand("mceReplaceContent",!1,newContent)}}})})),ed.addButton("medialibrary",{icon:"image",title:"Insert media",cmd:"mceMediaLibrary"})},createControl:function(n,cm){return null},getInfo:function(){return{longname:"Orchard Media Library Plugin",author:"The Orchard Team",authorurl:"http://orchardproject.net",infourl:"http://orchardproject.net",version:"1.1"}}}),tinymce.PluginManager.add("medialibrary",tinymce.plugins.Orchard.MediaLibrary);

View File

@ -0,0 +1,54 @@
tinymce.PluginManager.add('orchardcontentlinks', function (editor, url) {
var contentPickerAction = function () {
var data = {};
var callbackName = "_contentpicker_" + new Date().getTime();
data.callbackName = callbackName;
$[callbackName] = function (returnData) {
delete $[callbackName];
//the code to wrap text with link
var textLink = editor.selection.getContent();
if (!textLink || textLink == "") {
textLink = returnData.displayText;
}
editor.insertContent("<a href=\"#{ContentItem.Id:" + returnData.id.toString() + ".DisplayUrl}\">" + textLink + "</a>");
};
$[callbackName].data = data;
// Open content picker window
var baseUrl = baseOrchardPath;
// remove trailing slash if any
if (baseUrl.slice(-1) == '/')
baseUrl = baseUrl.substr(0, baseUrl.length - 1);
var url = baseUrl + "/Admin/Orchard.ContentPicker?";
url += "callback=" + callbackName + "&" + (new Date() - 0);
if ($("#" + editor.id).data("content-types")) {
url += "&types=" + $("#" + editor.id).data("content-types");
}
var w = window.open(url, "_blank", data.windowFeatures || "width=685,height=700,status=no,toolbar=no,location=no,menubar=no,resizable=no,scrollbars=yes");
}
// Add a button that opens a window
editor.addButton('orchardlink', {
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAABb0lEQVRIibWW223CQBBFDxEFUAIdJNHsf6CCkApiKgBXAFSAUgFJBdCB4X9HogSX4A6Sjx0rK8cGY5P7sw9Z93h3HvYAk4jbAk/cpgLYqPpz0wODCJDZ9NTSfBVBpk2QKuCk6tdt3EXcN5BGoFrIQ8u3bdIZeAZyIBNxf664LwBVnwPTJkhvgEGKJsiwp/dCxE2i9RFYAlsD9gIcgRHwUtkv4kVngKqf1u2LuHUMvUsMLunfAVevSMQtCUf+UvWHWwEXTyDidoSMGAF7EZfcDWDmCTC3gM6BnYgb9wZYoSSEXlP2l3LsDCiAQzTPgXd+KzMDzqr+2Amg6t+AmXXViUHGBs0MWJv7rQB25yszWpn5xsYjoR0XVYNrGkbmCSGQr4SsyYG8qWLbqjxBAqSq/hP4MNDYQL1UFloBPEbzPeEENxdWEyAl5PiIEOCcjndeVfxNngELM08NdOtfBlgnLWM3qHvC8n7bwbzUWdWnAD+rk38HDdeC5gAAAABJRU5ErkJggg==',
tooltip: 'Content link',
onclick: contentPickerAction
});
// Adds a menu item to the tools menu
editor.addMenuItem('orchardlink ', {
text: 'content link',
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAABb0lEQVRIibWW223CQBBFDxEFUAIdJNHsf6CCkApiKgBXAFSAUgFJBdCB4X9HogSX4A6Sjx0rK8cGY5P7sw9Z93h3HvYAk4jbAk/cpgLYqPpz0wODCJDZ9NTSfBVBpk2QKuCk6tdt3EXcN5BGoFrIQ8u3bdIZeAZyIBNxf664LwBVnwPTJkhvgEGKJsiwp/dCxE2i9RFYAlsD9gIcgRHwUtkv4kVngKqf1u2LuHUMvUsMLunfAVevSMQtCUf+UvWHWwEXTyDidoSMGAF7EZfcDWDmCTC3gM6BnYgb9wZYoSSEXlP2l3LsDCiAQzTPgXd+KzMDzqr+2Amg6t+AmXXViUHGBs0MWJv7rQB25yszWpn5xsYjoR0XVYNrGkbmCSGQr4SsyYG8qWLbqjxBAqSq/hP4MNDYQL1UFloBPEbzPeEENxdWEyAl5PiIEOCcjndeVfxNngELM08NdOtfBlgnLWM3qHvC8n7bwbzUWdWnAD+rk38HDdeC5gAAAABJRU5ErkJggg==',
context: 'insert',
onclick: contentPickerAction
});
return {
getMetadata: function () {
return {
name: "Orchard content link plugin"
};
}
};
});

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