Merge branch '1.7.x' into 1.x

This commit is contained in:
Sebastien Ros
2014-02-03 16:32:08 -08:00
25 changed files with 691 additions and 441 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@
[Rr]elease/
x64/
build/
app.publish/
[Bb]in/
[Oo]bj/

View File

@@ -7,9 +7,14 @@
<autofac defaultAssembly="Orchard.Framework">
<components>
<!-- Configure Orchard to store shell settings in Windows Azure Blob Storage. -->
<component instance-scope="single-instance" type="Orchard.FileSystems.Media.ConfigurationMimeTypeProvider, Orchard.Framework" service="Orchard.FileSystems.Media.IMimeTypeProvider"></component>
<component instance-scope="single-instance" type="Orchard.Azure.Services.Environment.Configuration.AzureBlobShellSettingsManager, Orchard.Azure" service="Orchard.Environment.Configuration.IShellSettingsManager"></component>
<!-- Configure Orchard to use role instance ID instead of Windows machine name for task lease records. -->
<component instance-scope="single-instance" type="Orchard.Azure.Services.TaskLease.AzureMachineNameProvider, Orchard.Azure" service="Orchard.TaskLease.Services.IMachineNameProvider, Orchard.TaskLease"></component>
</components>
</autofac>

View File

@@ -425,6 +425,10 @@
<Name>Orchard.Search</Name>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\Orchard.Web\Modules\Orchard.SecureSocketsLayer\Orchard.SecureSocketsLayer.csproj">
<Project>{36b82383-d69e-4897-a24a-648babdf80ec}</Project>
<Name>Orchard.SecureSocketsLayer</Name>
</ProjectReference>
<ProjectReference Include="..\..\Orchard.Web\Modules\Orchard.Setup\Orchard.Setup.csproj">
<Project>{8C7FCBC2-E6E1-405E-BFB5-D8D9E67A09C4}</Project>
<Name>Orchard.Setup</Name>

View File

@@ -141,6 +141,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Orchard", "Orchard", "{F2AB
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Caching", "..\Orchard.Web\Modules\Orchard.Caching\Orchard.Caching.csproj", "{7528BF74-25C7-4ABE-883A-443B4EEC4776}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.SecureSocketsLayer", "..\Orchard.Web\Modules\Orchard.SecureSocketsLayer\Orchard.SecureSocketsLayer.csproj", "{36B82383-D69E-4897-A24A-648BABDF80EC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -403,6 +405,10 @@ Global
{7528BF74-25C7-4ABE-883A-443B4EEC4776}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7528BF74-25C7-4ABE-883A-443B4EEC4776}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7528BF74-25C7-4ABE-883A-443B4EEC4776}.Release|Any CPU.Build.0 = Release|Any CPU
{36B82383-D69E-4897-A24A-648BABDF80EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36B82383-D69E-4897-A24A-648BABDF80EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36B82383-D69E-4897-A24A-648BABDF80EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36B82383-D69E-4897-A24A-648BABDF80EC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -461,6 +467,7 @@ Global
{5D13EF34-8B39-4EC5-847F-E12892ACF841} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{E649EA64-D213-461B-87F7-D67035801443} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{7528BF74-25C7-4ABE-883A-443B4EEC4776} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{36B82383-D69E-4897-A24A-648BABDF80EC} = {8E3DE014-9B28-4B32-8AC1-B2BE404E9B2D}
{33B1BC8D-E292-4972-A363-22056B207156} = {75E7476C-C05B-4C41-8E38-081D3EB55659}
{CB70A642-8CEC-4DDE-8C9F-AD08900EC98D} = {84650275-884D-4CBB-9CC0-67553996E211}
{9916839C-39FC-4CEB-A5AF-89CA7E87119F} = {F2AB7512-139A-420F-AE3A-9ED22CA52CE1}

View File

@@ -61,7 +61,7 @@
<!-- Prevents Orchard.exe from displaying locking debug messages. -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %logger - %message%newline" />
<conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message%newline" />
</layout>
</appender>
@@ -81,7 +81,7 @@
<levelMin value="ERROR" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %logger - %message%newline" />
<conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message%newline %P{Url}%newline" />
</layout>
</appender>

View File

@@ -71,6 +71,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Diagnostics.StorageUtility.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.ServiceRuntime, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.ServiceRuntime.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Storage.dll</HintPath>
@@ -89,6 +93,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Services\TaskLease\AzureMachineNameProvider.cs" />
<Content Include="Web.config" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Module.txt" />
@@ -102,6 +107,10 @@
<Project>{6e444ff1-a47c-4cf6-bb3f-507c8ebd776d}</Project>
<Name>Orchard.OutputCache</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.TaskLease\Orchard.TaskLease.csproj">
<Project>{3f72a4e9-7b72-4260-b010-c16ec54f9baf}</Project>
<Name>Orchard.TaskLease</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Constants.cs" />

View File

@@ -67,15 +67,7 @@ namespace Orchard.Azure.Services.FileSystems {
// The container is named with DNS naming restrictions (i.e. all lower case)
_container = _blobClient.GetContainerReference(ContainerName);
_container.CreateIfNotExists();
_container.SetPermissions(_isPrivate
? new BlobContainerPermissions {
PublicAccess = BlobContainerPublicAccessType.Off
}
: new BlobContainerPermissions {
PublicAccess = BlobContainerPublicAccessType.Container
});
_container.CreateIfNotExists(_isPrivate ? BlobContainerPublicAccessType.Off : BlobContainerPublicAccessType.Container);
}
private static string ConvertToRelativeUriPath(string path) {

View File

@@ -10,15 +10,7 @@ namespace Orchard.Azure.Services.FileSystems {
public static bool BlobExists(this CloudBlobContainer container, string path) {
if (String.IsNullOrEmpty(path) || path.Trim() == String.Empty)
throw new ArgumentException("Path can't be empty");
try {
var blob = container.GetBlockBlobReference(path);
blob.FetchAttributes();
return true;
}
catch (StorageException) {
return false;
}
return container.GetBlockBlobReference(path).Exists();
}
public static void EnsureBlobExists(this CloudBlobContainer container, string path) {

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure.ServiceRuntime;
using Orchard.TaskLease.Services;
namespace Orchard.Azure.Services.TaskLease
{
public class AzureMachineNameProvider : IMachineNameProvider
{
public string GetMachineName()
{
return RoleEnvironment.CurrentRoleInstance.Id;
}
}
}

View File

@@ -21,10 +21,10 @@ namespace Orchard.CodeGeneration.Commands {
private const string SolutionDirectoryThemes = "74492CBC-7201-417E-BC29-28B4C25A58B0";
private static readonly string[] _themeDirectories = new[] {
"", "Content", "Styles", "Scripts", "Views", "Zones"
"", "Content", "Styles", "Scripts", "Views"
};
private static readonly string[] _moduleDirectories = new[] {
"", "Properties", "Controllers", "Views", "Models", "Scripts", "Styles"
"", "Properties", "Controllers", "Views", "Models", "Scripts", "Styles"
};
private static readonly string[] _moduleTestsDirectories = new[] {
"", "Properties"

View File

@@ -35,19 +35,19 @@ namespace Orchard.Comments.Controllers {
var editorShape = Services.ContentManager.UpdateEditor(comment, this);
if (!ModelState.IsValidField("Author")) {
if (!ModelState.IsValidField("Comments.Author")) {
Services.Notifier.Error(T("Name is mandatory and must have less than 255 chars"));
}
if (!ModelState.IsValidField("Email")) {
if (!ModelState.IsValidField("Comments.Email")) {
Services.Notifier.Error(T("Email is invalid or is longer than 255 chars"));
}
if (!ModelState.IsValidField("Site")) {
if (!ModelState.IsValidField("Comments.Site")) {
Services.Notifier.Error(T("Site url is invalid or is longer than 255 chars"));
}
if (!ModelState.IsValidField("CommentText")) {
if (!ModelState.IsValidField("Comments.CommentText")) {
Services.Notifier.Error(T("Comment is mandatory"));
}

View File

@@ -177,7 +177,7 @@ namespace Orchard.ContentPermissions.Drivers {
}
if (!_authorizer.Authorize(Core.Contents.Permissions.PublishOwnContent, part.ContentItem)) {
part.PublishOwnContent = settings == null ? ContentPermissionsPartViewModel.SerializePermissions(allRoles.Select(x => new RoleEntry {Role = x, Checked = _authorizationService.TryCheckAccess(Core.Contents.Permissions.ViewContent, UserSimulation.Create(x), null)})) : settings.PublishOwn;
part.PublishOwnContent = settings == null ? ContentPermissionsPartViewModel.SerializePermissions(allRoles.Select(x => new RoleEntry {Role = x, Checked = _authorizationService.TryCheckAccess(Core.Contents.Permissions.PublishOwnContent, UserSimulation.Create(x), null)})) : settings.PublishOwn;
}
if (!_authorizer.Authorize(Core.Contents.Permissions.EditContent, part.ContentItem)) {

View File

@@ -28,13 +28,6 @@
</label>
@Html.HiddenFor(m => m.ViewRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.PublishRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
<input type="checkbox" value="true" @if (Model.PublishRoles.Any(x => x.Role == role.Name && x.Checked)) { <text>checked="checked"</text> } name="@Html.FieldNameFor(m => m.PublishRoles[role.Index].Checked)" id="@Html.FieldIdFor(m => m.PublishRoles[role.Index].Checked)" @if (!Model.PublishRoles[role.Index].Enabled) { <text>disabled="disabled"</text> }/>
</label>
@Html.HiddenFor(m => m.PublishRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.EditRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
@@ -42,6 +35,13 @@
</label>
@Html.HiddenFor(m => m.EditRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.PublishRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
<input type="checkbox" value="true" @if (Model.PublishRoles.Any(x => x.Role == role.Name && x.Checked)) { <text>checked="checked"</text> } name="@Html.FieldNameFor(m => m.PublishRoles[role.Index].Checked)" id="@Html.FieldIdFor(m => m.PublishRoles[role.Index].Checked)" @if (!Model.PublishRoles[role.Index].Enabled) { <text>disabled="disabled"</text> }/>
</label>
@Html.HiddenFor(m => m.PublishRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.DeleteRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
@@ -72,13 +72,6 @@
</label>
@Html.HiddenFor(m => m.ViewOwnRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.PublishOwnRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
<input type="checkbox" value="true" @if (Model.PublishOwnRoles.Any(x => x.Role == role.Name && x.Checked)) { <text>checked="checked"</text> } name="@Html.FieldNameFor(m => m.PublishOwnRoles[role.Index].Checked)" id="@Html.FieldIdFor(m => m.PublishOwnRoles[role.Index].Checked)" @if (!Model.PublishOwnRoles[role.Index].Enabled) { <text>disabled="disabled"</text> }/>
</label>
@Html.HiddenFor(m => m.PublishOwnRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.EditOwnRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
@@ -86,6 +79,13 @@
</label>
@Html.HiddenFor(m => m.EditOwnRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.PublishOwnRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>
<input type="checkbox" value="true" @if (Model.PublishOwnRoles.Any(x => x.Role == role.Name && x.Checked)) { <text>checked="checked"</text> } name="@Html.FieldNameFor(m => m.PublishOwnRoles[role.Index].Checked)" id="@Html.FieldIdFor(m => m.PublishOwnRoles[role.Index].Checked)" @if (!Model.PublishOwnRoles[role.Index].Enabled) { <text>disabled="disabled"</text> }/>
</label>
@Html.HiddenFor(m => m.PublishOwnRoles[role.Index].Role)
</td>
<td>
<label>
<input type="checkbox" disabled="disabled" @if (Model.DeleteOwnRoles.Any(x => x.Role == role.Name && x.Default)) { <text>checked="checked"</text> } title="Default value"/>

View File

@@ -15,25 +15,19 @@ namespace Orchard.CustomForms {
public static readonly Permission ManageForms = new Permission { Description = "Manage custom forms", Name = "ManageForms" };
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IContentManager _contentManager;
public virtual Feature Feature { get; set; }
public Permissions(IContentDefinitionManager contentDefinitionManager, IContentManager contentManager) {
public Permissions(IContentDefinitionManager contentDefinitionManager) {
_contentDefinitionManager = contentDefinitionManager;
_contentManager = contentManager;
}
public IEnumerable<Permission> GetPermissions() {
// manage rights only for Creatable types
var formTypes = _contentManager.Query<CustomFormPart>().List().Select(x => x.ContentType).Distinct();
foreach (var contentType in formTypes) {
var typeDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
if(typeDefinition == null) {
continue;
}
var formTypeDefinitions = _contentDefinitionManager
.ListTypeDefinitions()
.Where(x => x.Parts.Any(xx => xx.PartDefinition.Name == typeof(CustomFormPart).Name));
foreach (var typeDefinition in formTypeDefinitions) {
yield return CreateSubmitPermission(typeDefinition);
}

View File

@@ -60,7 +60,7 @@
var multiple = @(settings.Multiple ? "true" : "false");
var addButton = $('#btn-@fieldIdForIds');
var @(fieldIdForIds)_Template =
'<li><div data-id="{contentItemId}" data-fieldid="@fieldIdForIds" class="media-library-picker-item"><div class="thumbnail">{thumbnail}<div class="overlay"><h3>{title}</h3></div><div></div><a href="#" data-id="{contentItemId}" class="media-library-picker-remove">@T("Remove")</a>@T(" | ")<a href="{editLink}?ReturnUrl=@Request.RawUrl">@T("Edit")</a></li>';
'<li><div data-id="{contentItemId}" data-fieldid="@fieldIdForIds" class="media-library-picker-item"><div class="thumbnail">{thumbnail}<div class="overlay"><h3>{title}</h3></div></div></div><a href="#" data-id="{contentItemId}" class="media-library-picker-remove">@T("Remove")</a>@T(" | ")<a href="{editLink}?ReturnUrl=@Request.RawUrl">@T("Edit")</a></li>';
var refreshIds = function() {
var id = $('#@fieldIdForSelectedIds');

View File

@@ -4,12 +4,26 @@ using Orchard.Environment.Extensions.Models;
namespace Orchard.MultiTenancy.Services {
public interface ITenantService : IDependency {
/// <summary>
/// Retrieves all tenants' shell settings.
/// </summary>
/// <returns>All tenants' shell settings.</returns>
IEnumerable<ShellSettings> GetTenants();
/// <summary>
/// Creates a new tenant.
/// </summary>
/// <param name="settings">Shell settings of the tenant.</param>
void CreateTenant(ShellSettings settings);
/// <summary>
/// Updates the shell settings of a tenant.
/// </summary>
/// <param name="settings">Shell settings of the tenant.</param>
void UpdateTenant(ShellSettings settings);
/// <summary>
/// Returns a list of all installed themes
/// Returns a list of all installed themes.
/// </summary>
IEnumerable<ExtensionDescriptor> GetInstalledThemes();

View File

@@ -53,7 +53,8 @@ namespace Orchard.SecureSocketsLayer.Filters {
// non auth page on a secure canal
// nb: needed as the ReturnUrl for LogOn doesn't force the scheme to http, and reuses the current one
if (!secure && request.IsSecureConnection) {
// Also don't force http on ajax requests.
if (!secure && request.IsSecureConnection && !request.IsAjaxRequest()) {
var insecureActionUrl = AppendQueryString(
request.QueryString,
_sslService.InsecureActionUrl(

View File

@@ -1,137 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Taxonomies.Models;
using Orchard.Taxonomies.Services;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Feeds;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Settings;
using Orchard.UI.Navigation;
namespace Orchard.Taxonomies.Drivers {
public class TermPartDriver : ContentPartDriver<TermPart> {
private readonly ITaxonomyService _taxonomyService;
private readonly ISiteService _siteService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IFeedManager _feedManager;
private readonly IContentManager _contentManager;
public TermPartDriver(
ITaxonomyService taxonomyService,
ISiteService siteService,
IHttpContextAccessor httpContextAccessor,
IFeedManager feedManager,
IContentManager contentManager) {
_taxonomyService = taxonomyService;
_siteService = siteService;
_httpContextAccessor = httpContextAccessor;
_feedManager = feedManager;
_contentManager = contentManager;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected override string Prefix { get { return "Term"; } }
protected override DriverResult Display(TermPart part, string displayType, dynamic shapeHelper) {
return Combined(
ContentShape("Parts_TermPart_Feed", () => {
// generates a link to the RSS feed for this term
_feedManager.Register(part.Name, "rss", new RouteValueDictionary { { "term", part.Id } });
return null;
}),
ContentShape("Parts_TermPart", () => {
var pagerParameters = new PagerParameters();
var httpContext = _httpContextAccessor.Current();
if (httpContext != null) {
pagerParameters.Page = Convert.ToInt32(httpContext.Request.QueryString["page"]);
}
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var taxonomy = _taxonomyService.GetTaxonomy(part.TaxonomyId);
var totalItemCount = _taxonomyService.GetContentItemsCount(part);
// asign Taxonomy and Term to the content item shape (Content) in order to provide
// alternates when those content items are displayed when they are listed on a term
var termContentItems = _taxonomyService.GetContentItems(part, pager.GetStartIndex(), pager.PageSize)
.Select(c => _contentManager.BuildDisplay(c, "Summary").Taxonomy(taxonomy).Term(part));
var list = shapeHelper.List();
list.AddRange(termContentItems);
var pagerShape = shapeHelper.Pager(pager)
.TotalItemCount(totalItemCount)
.Taxonomy(taxonomy)
.Term(part);
return shapeHelper.Parts_TermPart(ContentItems: list, Taxonomy: taxonomy, Pager: pagerShape);
}));
}
protected override DriverResult Editor(TermPart part, dynamic shapeHelper) {
return ContentShape("Parts_Taxonomies_Term_Fields",
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Taxonomies.Term.Fields", Model: part, Prefix: Prefix));
}
protected override DriverResult Editor(TermPart termPart, IUpdateModel updater, dynamic shapeHelper) {
if (updater.TryUpdateModel(termPart, Prefix, null, null)) {
var existing = _taxonomyService.GetTermByName(termPart.TaxonomyId, termPart.Name);
if (existing != null && existing.Record != termPart.Record && existing.Container.ContentItem.Record == termPart.Container.ContentItem.Record) {
updater.AddModelError("Name", T("The term {0} already exists at this level", termPart.Name));
}
}
return Editor(termPart, shapeHelper);
}
protected override void Exporting(TermPart part, ExportContentContext context) {
context.Element(part.PartDefinition.Name).SetAttributeValue("Count", part.Count);
context.Element(part.PartDefinition.Name).SetAttributeValue("Selectable", part.Selectable);
context.Element(part.PartDefinition.Name).SetAttributeValue("Weight", part.Weight);
var taxonomy = _contentManager.Get(part.TaxonomyId);
var identity = _contentManager.GetItemMetadata(taxonomy).Identity.ToString();
context.Element(part.PartDefinition.Name).SetAttributeValue("TaxonomyId", identity);
var identityPaths = new List<string>();
foreach(var pathPart in part.Path.Split('/')) {
if(String.IsNullOrEmpty(pathPart)) {
continue;
}
var parent = _contentManager.Get(Int32.Parse(pathPart));
identityPaths.Add(_contentManager.GetItemMetadata(parent).Identity.ToString());
}
context.Element(part.PartDefinition.Name).SetAttributeValue("Path", String.Join(",", identityPaths.ToArray()));
}
protected override void Importing(TermPart part, ImportContentContext context) {
part.Count = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Count"));
part.Selectable = Boolean.Parse(context.Attribute(part.PartDefinition.Name, "Selectable"));
part.Weight = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Weight"));
var identity = context.Attribute(part.PartDefinition.Name, "TaxonomyId");
var contentItem = context.GetItemFromSession(identity);
if (contentItem == null) {
throw new OrchardException(T("Unknown taxonomy: {0}", identity));
}
part.TaxonomyId = contentItem.Id;
part.Path = "/";
foreach(var identityPath in context.Attribute(part.PartDefinition.Name, "Path").Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries)) {
var pathContentItem = context.GetItemFromSession(identityPath);
part.Path += pathContentItem.Id + "/";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Taxonomies.Models;
using Orchard.Taxonomies.Services;
using Orchard.ContentManagement.Handlers;
using Orchard.Core.Feeds;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Settings;
using Orchard.Taxonomies.Settings;
using Orchard.UI.Navigation;
namespace Orchard.Taxonomies.Drivers {
public class TermPartDriver : ContentPartDriver<TermPart> {
private readonly ITaxonomyService _taxonomyService;
private readonly ISiteService _siteService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IFeedManager _feedManager;
private readonly IContentManager _contentManager;
public TermPartDriver(
ITaxonomyService taxonomyService,
ISiteService siteService,
IHttpContextAccessor httpContextAccessor,
IFeedManager feedManager,
IContentManager contentManager) {
_taxonomyService = taxonomyService;
_siteService = siteService;
_httpContextAccessor = httpContextAccessor;
_feedManager = feedManager;
_contentManager = contentManager;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected override string Prefix { get { return "Term"; } }
protected override DriverResult Display(TermPart part, string displayType, dynamic shapeHelper) {
return Combined(
ContentShape("Parts_TermPart_Feed", () => {
// generates a link to the RSS feed for this term
_feedManager.Register(part.Name, "rss", new RouteValueDictionary { { "term", part.Id } });
return null;
}),
ContentShape("Parts_TermPart", () => {
var pagerParameters = new PagerParameters();
var httpContext = _httpContextAccessor.Current();
if (httpContext != null) {
pagerParameters.Page = Convert.ToInt32(httpContext.Request.QueryString["page"]);
}
var pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var taxonomy = _taxonomyService.GetTaxonomy(part.TaxonomyId);
var totalItemCount = _taxonomyService.GetContentItemsCount(part);
var partSettings = part.Settings.GetModel<TermPartSettings>();
if (partSettings != null && partSettings.OverrideDefaultPagination) {
pager.PageSize = partSettings.PageSize;
}
var childDisplayType = partSettings != null &&
!String.IsNullOrWhiteSpace(partSettings.ChildDisplayType)
? partSettings.ChildDisplayType
: "Summary";
// asign Taxonomy and Term to the content item shape (Content) in order to provide
// alternates when those content items are displayed when they are listed on a term
var termContentItems = _taxonomyService.GetContentItems(part, pager.GetStartIndex(), pager.PageSize)
.Select(c => _contentManager.BuildDisplay(c, childDisplayType).Taxonomy(taxonomy).Term(part));
var list = shapeHelper.List();
list.AddRange(termContentItems);
var pagerShape = pager.PageSize == 0
? null
: shapeHelper.Pager(pager)
.TotalItemCount(totalItemCount)
.Taxonomy(taxonomy)
.Term(part);
return shapeHelper.Parts_TermPart(ContentItems: list, Taxonomy: taxonomy, Pager: pagerShape);
}));
}
protected override DriverResult Editor(TermPart part, dynamic shapeHelper) {
return ContentShape("Parts_Taxonomies_Term_Fields",
() => shapeHelper.EditorTemplate(TemplateName: "Parts/Taxonomies.Term.Fields", Model: part, Prefix: Prefix));
}
protected override DriverResult Editor(TermPart termPart, IUpdateModel updater, dynamic shapeHelper) {
if (updater.TryUpdateModel(termPart, Prefix, null, null)) {
var existing = _taxonomyService.GetTermByName(termPart.TaxonomyId, termPart.Name);
if (existing != null && existing.Record != termPart.Record && existing.Container.ContentItem.Record == termPart.Container.ContentItem.Record) {
updater.AddModelError("Name", T("The term {0} already exists at this level", termPart.Name));
}
}
return Editor(termPart, shapeHelper);
}
protected override void Exporting(TermPart part, ExportContentContext context) {
context.Element(part.PartDefinition.Name).SetAttributeValue("Count", part.Count);
context.Element(part.PartDefinition.Name).SetAttributeValue("Selectable", part.Selectable);
context.Element(part.PartDefinition.Name).SetAttributeValue("Weight", part.Weight);
var taxonomy = _contentManager.Get(part.TaxonomyId);
var identity = _contentManager.GetItemMetadata(taxonomy).Identity.ToString();
context.Element(part.PartDefinition.Name).SetAttributeValue("TaxonomyId", identity);
var identityPaths = new List<string>();
foreach(var pathPart in part.Path.Split('/')) {
if(String.IsNullOrEmpty(pathPart)) {
continue;
}
var parent = _contentManager.Get(Int32.Parse(pathPart));
identityPaths.Add(_contentManager.GetItemMetadata(parent).Identity.ToString());
}
context.Element(part.PartDefinition.Name).SetAttributeValue("Path", String.Join(",", identityPaths.ToArray()));
}
protected override void Importing(TermPart part, ImportContentContext context) {
part.Count = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Count"));
part.Selectable = Boolean.Parse(context.Attribute(part.PartDefinition.Name, "Selectable"));
part.Weight = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Weight"));
var identity = context.Attribute(part.PartDefinition.Name, "TaxonomyId");
var contentItem = context.GetItemFromSession(identity);
if (contentItem == null) {
throw new OrchardException(T("Unknown taxonomy: {0}", identity));
}
part.TaxonomyId = contentItem.Id;
part.Path = "/";
foreach(var identityPath in context.Attribute(part.PartDefinition.Name, "Path").Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries)) {
var pathContentItem = context.GetItemFromSession(identityPath);
part.Path += pathContentItem.Id + "/";
}
}
}
}

View File

@@ -1,240 +1,244 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E649EA64-D213-461B-87F7-D67035801443}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.Taxonomies</RootNamespace>
<AssemblyName>Orchard.Taxonomies</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>false</UseIISExpress>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\TermAdminController.cs" />
<Compile Include="Drivers\TaxonomyNavigationPartDriver.cs" />
<Compile Include="Drivers\TermsPartDriver.cs" />
<Compile Include="Drivers\TaxonomyPartDriver.cs" />
<Compile Include="Handlers\TaxonomyPartHandler.cs" />
<Compile Include="Handlers\TermsPartHandler.cs" />
<Compile Include="Helpers\PathExtensions.cs" />
<Compile Include="Migrations.cs" />
<Compile Include="Drivers\TermPartDriver.cs" />
<Compile Include="Drivers\TaxonomyFieldDriver.cs" />
<Compile Include="Handlers\TermPartHandler.cs" />
<Compile Include="Helpers\PredicateBuilder.cs" />
<Compile Include="Models\TaxonomyNavigationPart.cs" />
<Compile Include="Models\TermContentItemPart.cs" />
<Compile Include="Models\TaxonomyPartRecord.cs" />
<Compile Include="Models\TermPart.cs" />
<Compile Include="Models\TermPartNode.cs" />
<Compile Include="Models\TermPartRecord.cs" />
<Compile Include="Models\TaxonomyPart.cs" />
<Compile Include="Models\TermContentItem.cs" />
<Compile Include="Models\TermsPart.cs" />
<Compile Include="Models\TermsPartRecord.cs" />
<Compile Include="Navigation\TaxonomyNavigationProvider.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Projections\TermsFilter.cs" />
<Compile Include="Projections\TermsFilterForms.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Fields\TaxonomyField.cs" />
<Compile Include="Services\ITaxonomyService.cs" />
<Compile Include="Services\TaxonomyService.cs" />
<Compile Include="Settings\TaxonomyFieldEditorEvents.cs" />
<Compile Include="Settings\TaxonomyFieldSettings.cs" />
<Compile Include="Shapes.cs" />
<Compile Include="StandardQueries\TermFeedQuery.cs" />
<Compile Include="Tokens\TaxonomyTokens.cs" />
<Compile Include="ViewModels\ImportViewModel.cs" />
<Compile Include="ViewModels\MergeTermViewModel.cs" />
<Compile Include="ViewModels\MoveTermViewModel.cs" />
<Compile Include="ViewModels\SelectTermViewModel.cs" />
<Compile Include="ViewModels\TaxonomyFieldViewModel.cs" />
<Compile Include="ViewModels\TermAdminIndexViewModel.cs" />
<Compile Include="ViewModels\TaxonomyAdminIndexViewModel.cs" />
<Compile Include="ViewModels\TaxonomyNavigationViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\admin-taxonomy-expando.js" />
<Content Include="Scripts\admin-taxonomy-field-settings.js" />
<Content Include="Scripts\admin-taxonomy-tags.js" />
<Content Include="Scripts\tagit.js" />
<Content Include="Styles\admin-taxonomy-tags.css" />
<Content Include="Styles\images\menu.taxonomies.png" />
<Content Include="Styles\menu.taxonomies-admin.css" />
<Content Include="Styles\ui-anim_basic_16x16.gif" />
<Content Include="Views\Admin\Import.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Styles\admin-taxonomy.css" />
<Content Include="Module.txt" />
<Content Include="Views\Admin\Edit.cshtml" />
<Content Include="Views\Admin\Create.cshtml" />
<Content Include="Views\Admin\Index.cshtml" />
<Content Include="Views\DefinitionTemplates\TaxonomyFieldSettings.cshtml" />
<Content Include="Views\Fields\TaxonomyField.cshtml" />
<Content Include="Views\EditorTemplates\Parts\Taxonomies.Term.Fields.cshtml" />
<Content Include="Views\Items\Content-Term.Edit.cshtml" />
<Content Include="Views\TermAdmin\Create.cshtml" />
<Content Include="Views\TermAdmin\Edit.cshtml" />
<Content Include="Views\TermAdmin\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Placement.info">
<SubType>Designer</SubType>
</Content>
<Content Include="Styles\Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Views\TermAdmin\RenderTermSelect.cshtml" />
<Content Include="Views\TermAdmin\MoveTerm.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Home\List.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Views\TermAdmin\SelectTerm.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="web.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839c-39fc-4ceb-a5af-89ca7e87119f}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Alias\Orchard.Alias.csproj">
<Project>{475b6c45-b27c-438b-8966-908b9d6d1077}</Project>
<Name>Orchard.Alias</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Autoroute\Orchard.Autoroute.csproj">
<Project>{66fccd76-2761-47e3-8d11-b45d0001ddaa}</Project>
<Name>Orchard.Autoroute</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Fields\TaxonomyField.Autocomplete.cshtml" />
<Content Include="Views\EditorTemplates\Fields\TaxonomyField.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\TermAdmin\Merge.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Parts.TaxonomyPart.cshtml">
<SubType>Code</SubType>
</Content>
<Content Include="Views\Parts.TermPart.cshtml" />
<Content Include="Views\Taxonomy.cshtml" />
<Content Include="Views\TaxonomyItem.cshtml" />
<Content Include="Views\TaxonomyItemLink.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\Navigation.Taxonomy.Edit.cshtml" />
</ItemGroup>
<ItemGroup />
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target> -->
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>2078</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E649EA64-D213-461B-87F7-D67035801443}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Orchard.Taxonomies</RootNamespace>
<AssemblyName>Orchard.Taxonomies</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>false</UseIISExpress>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Routing" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\TermAdminController.cs" />
<Compile Include="Drivers\TaxonomyNavigationPartDriver.cs" />
<Compile Include="Drivers\TermsPartDriver.cs" />
<Compile Include="Drivers\TaxonomyPartDriver.cs" />
<Compile Include="Handlers\TaxonomyPartHandler.cs" />
<Compile Include="Handlers\TermsPartHandler.cs" />
<Compile Include="Helpers\PathExtensions.cs" />
<Compile Include="Migrations.cs" />
<Compile Include="Drivers\TermPartDriver.cs" />
<Compile Include="Drivers\TaxonomyFieldDriver.cs" />
<Compile Include="Handlers\TermPartHandler.cs" />
<Compile Include="Helpers\PredicateBuilder.cs" />
<Compile Include="Models\TaxonomyNavigationPart.cs" />
<Compile Include="Models\TermContentItemPart.cs" />
<Compile Include="Models\TaxonomyPartRecord.cs" />
<Compile Include="Models\TermPart.cs" />
<Compile Include="Models\TermPartNode.cs" />
<Compile Include="Models\TermPartRecord.cs" />
<Compile Include="Models\TaxonomyPart.cs" />
<Compile Include="Models\TermContentItem.cs" />
<Compile Include="Models\TermsPart.cs" />
<Compile Include="Models\TermsPartRecord.cs" />
<Compile Include="Navigation\TaxonomyNavigationProvider.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Projections\TermsFilter.cs" />
<Compile Include="Projections\TermsFilterForms.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Fields\TaxonomyField.cs" />
<Compile Include="Services\ITaxonomyService.cs" />
<Compile Include="Services\TaxonomyService.cs" />
<Compile Include="Settings\TermPartEditorEvents.cs" />
<Compile Include="Settings\TaxonomyFieldEditorEvents.cs" />
<Compile Include="Settings\TermPartSettings.cs" />
<Compile Include="Settings\TaxonomyFieldSettings.cs" />
<Compile Include="Shapes.cs" />
<Compile Include="StandardQueries\TermFeedQuery.cs" />
<Compile Include="Tokens\TaxonomyTokens.cs" />
<Compile Include="ViewModels\ImportViewModel.cs" />
<Compile Include="ViewModels\MergeTermViewModel.cs" />
<Compile Include="ViewModels\MoveTermViewModel.cs" />
<Compile Include="ViewModels\SelectTermViewModel.cs" />
<Compile Include="ViewModels\TaxonomyFieldViewModel.cs" />
<Compile Include="ViewModels\TermAdminIndexViewModel.cs" />
<Compile Include="ViewModels\TaxonomyAdminIndexViewModel.cs" />
<Compile Include="ViewModels\TaxonomyNavigationViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\admin-taxonomy-expando.js" />
<Content Include="Scripts\admin-taxonomy-field-settings.js" />
<Content Include="Scripts\admin-taxonomy-tags.js" />
<Content Include="Scripts\tagit.js" />
<Content Include="Styles\admin-taxonomy-tags.css" />
<Content Include="Styles\images\menu.taxonomies.png" />
<Content Include="Styles\menu.taxonomies-admin.css" />
<Content Include="Styles\ui-anim_basic_16x16.gif" />
<Content Include="Views\Admin\Import.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Styles\admin-taxonomy.css" />
<Content Include="Module.txt" />
<Content Include="Views\Admin\Edit.cshtml" />
<Content Include="Views\Admin\Create.cshtml" />
<Content Include="Views\Admin\Index.cshtml" />
<Content Include="Views\DefinitionTemplates\TaxonomyFieldSettings.cshtml" />
<Content Include="Views\Fields\TaxonomyField.cshtml" />
<Content Include="Views\EditorTemplates\Parts\Taxonomies.Term.Fields.cshtml" />
<Content Include="Views\Items\Content-Term.Edit.cshtml" />
<Content Include="Views\TermAdmin\Create.cshtml" />
<Content Include="Views\TermAdmin\Edit.cshtml" />
<Content Include="Views\TermAdmin\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Placement.info">
<SubType>Designer</SubType>
</Content>
<Content Include="Styles\Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Views\TermAdmin\RenderTermSelect.cshtml" />
<Content Include="Views\TermAdmin\MoveTerm.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Home\List.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Scripts\Web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Views\TermAdmin\SelectTerm.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="web.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
<Project>{2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}</Project>
<Name>Orchard.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
<Project>{9916839c-39fc-4ceb-a5af-89ca7e87119f}</Project>
<Name>Orchard.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Alias\Orchard.Alias.csproj">
<Project>{475b6c45-b27c-438b-8966-908b9d6d1077}</Project>
<Name>Orchard.Alias</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Autoroute\Orchard.Autoroute.csproj">
<Project>{66fccd76-2761-47e3-8d11-b45d0001ddaa}</Project>
<Name>Orchard.Autoroute</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Tokens\Orchard.Tokens.csproj">
<Project>{6f759635-13d7-4e94-bcc9-80445d63f117}</Project>
<Name>Orchard.Tokens</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Fields\TaxonomyField.Autocomplete.cshtml" />
<Content Include="Views\EditorTemplates\Fields\TaxonomyField.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\TermAdmin\Merge.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Parts.TaxonomyPart.cshtml">
<SubType>Code</SubType>
</Content>
<Content Include="Views\Parts.TermPart.cshtml" />
<Content Include="Views\Taxonomy.cshtml" />
<Content Include="Views\TaxonomyItem.cshtml" />
<Content Include="Views\TaxonomyItemLink.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\Navigation.Taxonomy.Edit.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\DefinitionTemplates\TermPartSettings.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target> -->
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>2078</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://orchard.codeplex.com</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Globalization;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.ViewModels;
namespace Orchard.Taxonomies.Settings {
public class TermPartEditorEvents : ContentDefinitionEditorEventsBase {
public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition) {
if (definition.PartDefinition.Name == "TermPart") {
var model = definition.Settings.GetModel<TermPartSettings>();
yield return DefinitionTemplate(model);
}
}
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
if (builder.Name != "TermPart") {
yield break;
}
var model = new TermPartSettings();
if (updateModel.TryUpdateModel(model, "TermPartSettings", null, null)) {
builder
.WithSetting("TermPartSettings.ChildDisplayType", model.ChildDisplayType)
.WithSetting("TermPartSettings.OverrideDefaultPagination", model.OverrideDefaultPagination.ToString())
.WithSetting("TermPartSettings.PageSize", model.PageSize.ToString(CultureInfo.InvariantCulture));
}
yield return DefinitionTemplate(model);
}
}
}

View File

@@ -0,0 +1,18 @@
namespace Orchard.Taxonomies.Settings {
public class TermPartSettings {
/// <summary>
/// The display type to use for the child items of the term.
/// </summary>
public string ChildDisplayType { get; set; }
/// <summary>
/// If true, overrides default pagination settings with the PageSize value.
/// </summary>
public bool OverrideDefaultPagination { get; set; }
/// <summary>
/// The page size, if OverrideDefaultPagination is set to true.
/// </summary>
public int PageSize { get; set; }
}
}

View File

@@ -0,0 +1,19 @@
@model Orchard.Taxonomies.Settings.TermPartSettings
<fieldset>
<label for="@Html.FieldIdFor(m => m.ChildDisplayType)">@T("Child display type")</label>
@Html.TextBoxFor(m => m.ChildDisplayType, new { @class = "text medium" })
<span class="hint">@T("The display type to apply to child items when displaying the details of this taxonomy term.")</span>
@Html.ValidationMessageFor(m => m.ChildDisplayType)
</fieldset>
<fieldset>
<label>@T("Pagination")</label>
<div class="content">
@Html.CheckBoxFor(m => m.OverrideDefaultPagination)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.OverrideDefaultPagination)">@T("Override the default page size")</label>
</div>
<div data-controllerid="@Html.FieldIdFor(m => m.OverrideDefaultPagination)">
<label for="@Html.FieldIdFor(m => m.PageSize)">@T("Number of items per page")</label>
@Html.TextBoxFor(m => m.PageSize, new { @class = "text small" })
<span class="hint">@T("Determines the number of items that are shown per page.")</span>
</div>
</fieldset>

View File

@@ -2,7 +2,16 @@ using System.Collections.Generic;
namespace Orchard.Environment.Configuration {
public interface IShellSettingsManager {
/// <summary>
/// Retrieves all shell settings stored.
/// </summary>
/// <returns>All shell settings.</returns>
IEnumerable<ShellSettings> LoadSettings();
/// <summary>
/// Persists shell settings to the storage.
/// </summary>
/// <param name="settings">The shell settings to store.</param>
void SaveSettings(ShellSettings settings);
}
}

View File

@@ -1,6 +1,9 @@
using System;
using System.Globalization;
using System.Web;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using log4net;
using log4net.Core;
using log4net.Util;
@@ -9,10 +12,13 @@ using Logger = Castle.Core.Logging.ILogger;
namespace Orchard.Logging {
[Serializable]
public class OrchardLog4netLogger : MarshalByRefObject, Logger {
public class OrchardLog4netLogger : MarshalByRefObject, Logger, IShim {
private static readonly Type declaringType = typeof(OrchardLog4netLogger);
public IOrchardHostContainer HostContainer { get; set; }
private ShellSettings _shellSettings;
public OrchardLog4netLogger(log4net.Core.ILogger logger, OrchardLog4netFactory factory) {
OrchardHostContainerRegistry.RegisterShim(this);
Logger = logger;
Factory = factory;
}
@@ -24,6 +30,49 @@ namespace Orchard.Logging {
: this(log.Logger, factory) {
}
// Return a per class variable for each instance of the logger, which is for each tenant. This variable allows outputting the tenant name
private ShellSettings ShellSettings {
get {
if (_shellSettings == null) {
var ctx = HttpContext.Current;
if (ctx == null)
return null;
var runningShellTable = HostContainer.Resolve<IRunningShellTable>();
if (runningShellTable == null)
return null;
var shellSettings = runningShellTable.Match(new HttpContextWrapper(ctx));
if (shellSettings == null)
return null;
var orchardHost = HostContainer.Resolve<IOrchardHost>();
if (orchardHost == null)
return null;
var shellContext = orchardHost.GetShellContext(shellSettings);
if (shellContext == null || shellContext.Settings == null)
return null;
_shellSettings = shellContext.Settings;
}
return _shellSettings;
}
}
// Load the log4net thread with additional properties if they are available
protected internal void AddExtendedThreadInfo() {
if (ShellSettings != null) {
ThreadContext.Properties["Tenant"] = ShellSettings.Name;
}
var ctx = HttpContext.Current;
if (ctx != null) {
ThreadContext.Properties["Url"] = ctx.Request.Url.ToString();
}
}
public bool IsDebugEnabled {
get { return Logger.IsEnabledFor(Level.Debug); }
}
@@ -58,210 +107,245 @@ namespace Orchard.Logging {
public void Debug(String message) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, message, null);
}
}
public void Debug(Func<string> messageFactory) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, messageFactory.Invoke(), null);
}
}
public void Debug(String message, Exception exception) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, message, exception);
}
}
public void DebugFormat(String format, params Object[] args) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void DebugFormat(Exception exception, String format, params Object[] args) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void DebugFormat(IFormatProvider formatProvider, String format, params Object[] args) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void DebugFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args) {
if (IsDebugEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Debug, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Error(String message) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, message, null);
}
}
public void Error(Func<string> messageFactory) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, messageFactory.Invoke(), null);
}
}
public void Error(String message, Exception exception) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, message, exception);
}
}
public void ErrorFormat(String format, params Object[] args) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void ErrorFormat(Exception exception, String format, params Object[] args) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void ErrorFormat(IFormatProvider formatProvider, String format, params Object[] args) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void ErrorFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args) {
if (IsErrorEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Error, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Fatal(String message) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, message, null);
}
}
public void Fatal(Func<string> messageFactory) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, messageFactory.Invoke(), null);
}
}
public void Fatal(String message, Exception exception) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, message, exception);
}
}
public void FatalFormat(String format, params Object[] args) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void FatalFormat(Exception exception, String format, params Object[] args) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void FatalFormat(IFormatProvider formatProvider, String format, params Object[] args) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void FatalFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args) {
if (IsFatalEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Fatal, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Info(String message) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, message, null);
}
}
public void Info(Func<string> messageFactory) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, messageFactory.Invoke(), null);
}
}
public void Info(String message, Exception exception) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, message, exception);
}
}
public void InfoFormat(String format, params Object[] args) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void InfoFormat(Exception exception, String format, params Object[] args) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void InfoFormat(IFormatProvider formatProvider, String format, params Object[] args) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void InfoFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args) {
if (IsInfoEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Info, new SystemStringFormat(formatProvider, format, args), exception);
}
}
public void Warn(String message) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, message, null);
}
}
public void Warn(Func<string> messageFactory) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, messageFactory.Invoke(), null);
}
}
public void Warn(String message, Exception exception) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, message, exception);
}
}
public void WarnFormat(String format, params Object[] args) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), null);
}
}
public void WarnFormat(Exception exception, String format, params Object[] args) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, new SystemStringFormat(CultureInfo.InvariantCulture, format, args), exception);
}
}
public void WarnFormat(IFormatProvider formatProvider, String format, params Object[] args) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), null);
}
}
public void WarnFormat(Exception exception, IFormatProvider formatProvider, String format, params Object[] args) {
if (IsWarnEnabled) {
AddExtendedThreadInfo();
Logger.Log(declaringType, Level.Warn, new SystemStringFormat(formatProvider, format, args), exception);
}
}

View File

@@ -33,7 +33,9 @@ namespace Orchard.Security.Providers {
public void SignIn(IUser user, bool createPersistentCookie) {
var now = _clock.UtcNow.ToLocalTime();
var userData = Convert.ToString(user.Id);
// the cookie user data is {userId};{tenant}
var userData = String.Concat(Convert.ToString(user.Id), ";", _settings.Name);
var ticket = new FormsAuthenticationTicket(
1 /*version*/,
@@ -55,13 +57,7 @@ namespace Orchard.Security.Providers {
var httpContext = _httpContextAccessor.Current();
if (!String.IsNullOrEmpty(_settings.RequestUrlPrefix)) {
var cookiePath = httpContext.Request.ApplicationPath;
if (cookiePath != null && cookiePath.Length > 1) {
cookiePath += '/';
}
cookiePath += _settings.RequestUrlPrefix;
cookie.Path = cookiePath;
cookie.Path = GetCookiePath(httpContext);
}
if (FormsAuthentication.CookieDomain != null) {
@@ -82,6 +78,18 @@ namespace Orchard.Security.Providers {
_signedInUser = null;
_isAuthenticated = false;
FormsAuthentication.SignOut();
// overwritting the authentication cookie for the given tenant
var httpContext = _httpContextAccessor.Current();
var rFormsCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "") {
Expires = DateTime.Now.AddYears(-1),
};
if (!String.IsNullOrEmpty(_settings.RequestUrlPrefix)) {
rFormsCookie.Path = GetCookiePath(httpContext);
}
httpContext.Response.Cookies.Add(rFormsCookie);
}
public void SetAuthenticatedUserForRequest(IUser user) {
@@ -99,9 +107,24 @@ namespace Orchard.Security.Providers {
}
var formsIdentity = (FormsIdentity)httpContext.User.Identity;
var userData = formsIdentity.Ticket.UserData;
var userData = formsIdentity.Ticket.UserData ?? "";
// the cookie user data is {userId};{tenant}
var userDataSegments = userData.Split(';');
if (userDataSegments.Length != 2) {
return null;
}
var userDataId = userDataSegments[0];
var userDataTenant = userDataSegments[1];
if (!String.Equals(userDataTenant, _settings.Name, StringComparison.Ordinal)) {
return null;
}
int userId;
if (!int.TryParse(userData, out userId)) {
if (!int.TryParse(userDataId, out userId)) {
Logger.Fatal("User id not a parsable integer");
return null;
}
@@ -109,5 +132,16 @@ namespace Orchard.Security.Providers {
_isAuthenticated = true;
return _signedInUser = _contentManager.Get(userId).As<IUser>();
}
private string GetCookiePath(HttpContextBase httpContext) {
var cookiePath = httpContext.Request.ApplicationPath;
if (cookiePath != null && cookiePath.Length > 1) {
cookiePath += '/';
}
cookiePath += _settings.RequestUrlPrefix;
return cookiePath;
}
}
}