mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
- Infrastructure work towards ContentFields.
- Saving/Saved events - Some work on the content field definition, driver, driver handlers... --HG-- branch : dev
This commit is contained in:
@@ -1,8 +1,17 @@
|
|||||||
using Orchard.ContentManagement.MetaData.Models;
|
using System.Collections.Generic;
|
||||||
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
|
using Orchard.ContentManagement.Utilities;
|
||||||
|
|
||||||
namespace Orchard.ContentManagement {
|
namespace Orchard.ContentManagement {
|
||||||
public class ContentField {
|
public class ContentField : IContent {
|
||||||
|
public virtual ContentItem ContentItem { get; set;}
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public ContentFieldDefinition Definition { get; set; }
|
public ContentFieldDefinition Definition { get; set; }
|
||||||
|
public IDictionary<string, string> Settings { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContentField<TRecord> : ContentField {
|
||||||
|
public readonly LazyField<TRecord> _record = new LazyField<TRecord>();
|
||||||
|
public TRecord Record { get { return _record.Value; } set { _record.Value = value; } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
using Orchard.ContentManagement.Utilities;
|
using Orchard.ContentManagement.Utilities;
|
||||||
|
|
||||||
@@ -7,6 +8,8 @@ namespace Orchard.ContentManagement {
|
|||||||
public ContentTypeDefinition TypeDefinition { get { return ContentItem.TypeDefinition; } }
|
public ContentTypeDefinition TypeDefinition { get { return ContentItem.TypeDefinition; } }
|
||||||
public ContentTypeDefinition.Part TypePartDefinition { get; set; }
|
public ContentTypeDefinition.Part TypePartDefinition { get; set; }
|
||||||
public ContentPartDefinition PartDefinition { get { return TypePartDefinition.PartDefinition; } }
|
public ContentPartDefinition PartDefinition { get { return TypePartDefinition.PartDefinition; } }
|
||||||
|
|
||||||
|
public IEnumerable<ContentField> ContentFields { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContentPart<TRecord> : ContentPart {
|
public class ContentPart<TRecord> : ContentPart {
|
||||||
|
|||||||
51
src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs
Normal file
51
src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
|
|
||||||
|
namespace Orchard.ContentManagement.Drivers {
|
||||||
|
|
||||||
|
public interface IContentFieldDriver : IEvents {
|
||||||
|
DriverResult BuildDisplayModel(BuildDisplayModelContext context);
|
||||||
|
DriverResult BuildEditorModel(BuildEditorModelContext context);
|
||||||
|
DriverResult UpdateEditorModel(UpdateEditorModelContext context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ContentFieldDriver<TContent> : IContentFieldDriver where TContent : ContentField, new() {
|
||||||
|
protected virtual string Prefix { get { return ""; } }
|
||||||
|
protected virtual string Zone { get { return "body"; } }
|
||||||
|
|
||||||
|
DriverResult IContentFieldDriver.BuildDisplayModel(BuildDisplayModelContext context) {
|
||||||
|
var field = context.ContentItem.As<TContent>();
|
||||||
|
return field == null ? null : Display(field, context.DisplayType);
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverResult IContentFieldDriver.BuildEditorModel(BuildEditorModelContext context) {
|
||||||
|
var field = context.ContentItem.As<TContent>();
|
||||||
|
return field == null ? null : Editor(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverResult IContentFieldDriver.UpdateEditorModel(UpdateEditorModelContext context) {
|
||||||
|
var field = context.ContentItem.As<TContent>();
|
||||||
|
return field == null ? null : Editor(field, context.Updater);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual DriverResult Display(TContent field, string displayType) { return null; }
|
||||||
|
protected virtual DriverResult Editor(TContent field) { return null; }
|
||||||
|
protected virtual DriverResult Editor(TContent field, IUpdateModel updater) { return null; }
|
||||||
|
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult ContentPartTemplate(object model) {
|
||||||
|
return new ContentFieldTemplateResult(model, null, Prefix).Location(Zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult ContentPartTemplate(object model, string template) {
|
||||||
|
return new ContentFieldTemplateResult(model, template, Prefix).Location(Zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult ContentPartTemplate(object model, string template, string prefix) {
|
||||||
|
return new ContentFieldTemplateResult(model, template, prefix).Location(Zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombinedResult Combined(params DriverResult[] results) {
|
||||||
|
return new CombinedResult(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
|
using Orchard.Logging;
|
||||||
|
|
||||||
|
namespace Orchard.ContentManagement.Drivers {
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class ContentFieldDriverHandler : ContentHandlerBase {
|
||||||
|
private readonly IEnumerable<IContentPartDriver> _drivers;
|
||||||
|
|
||||||
|
public ContentFieldDriverHandler(IEnumerable<IContentPartDriver> drivers) {
|
||||||
|
_drivers = drivers;
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public override void BuildDisplayModel(BuildDisplayModelContext context) {
|
||||||
|
_drivers.Invoke(driver => {
|
||||||
|
var result = driver.BuildDisplayModel(context);
|
||||||
|
if (result != null)
|
||||||
|
result.Apply(context);
|
||||||
|
}, Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildEditorModel(BuildEditorModelContext context) {
|
||||||
|
_drivers.Invoke(driver => {
|
||||||
|
var result = driver.BuildEditorModel(context);
|
||||||
|
if (result != null)
|
||||||
|
result.Apply(context);
|
||||||
|
}, Logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateEditorModel(UpdateEditorModelContext context) {
|
||||||
|
_drivers.Invoke(driver => {
|
||||||
|
var result = driver.UpdateEditorModel(context);
|
||||||
|
if (result != null)
|
||||||
|
result.Apply(context);
|
||||||
|
}, Logger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
|
|
||||||
|
namespace Orchard.ContentManagement.Drivers {
|
||||||
|
public class ContentFieldTemplateResult : DriverResult {
|
||||||
|
public object Model { get; set; }
|
||||||
|
public string TemplateName { get; set; }
|
||||||
|
public string Prefix { get; set; }
|
||||||
|
public string Zone { get; set; }
|
||||||
|
public string Position { get; set; }
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult(object model, string templateName, string prefix) {
|
||||||
|
Model = model;
|
||||||
|
TemplateName = templateName;
|
||||||
|
Prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Apply(BuildDisplayModelContext context) {
|
||||||
|
context.ViewModel.Zones.AddDisplayPart(
|
||||||
|
Zone + ":" + Position, Model, TemplateName, Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Apply(BuildEditorModelContext context) {
|
||||||
|
context.ViewModel.Zones.AddEditorPart(
|
||||||
|
Zone + ":" + Position, Model, TemplateName, Prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult Location(string zone) {
|
||||||
|
Zone = zone;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult Location(string zone, string position) {
|
||||||
|
Zone = zone;
|
||||||
|
Position = position;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentFieldTemplateResult LongestMatch(string displayType, params string[] knownDisplayTypes) {
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(displayType))
|
||||||
|
return this;
|
||||||
|
|
||||||
|
var longest = knownDisplayTypes.Aggregate("", (best, x) => {
|
||||||
|
if (displayType.StartsWith(x) && x.Length > best.Length) return x;
|
||||||
|
return best;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(longest))
|
||||||
|
return this;
|
||||||
|
|
||||||
|
TemplateName += "." + longest;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
Filters.Add(new InlineStorageFilter<TPart> { OnCreated = handler });
|
Filters.Add(new InlineStorageFilter<TPart> { OnCreated = handler });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void OnSaving<TPart>(Action<SaveContentContext, TPart> handler) where TPart : class, IContent {
|
||||||
|
Filters.Add(new InlineStorageFilter<TPart> { OnSaving = handler });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnSaved<TPart>(Action<SaveContentContext, TPart> handler) where TPart : class, IContent {
|
||||||
|
Filters.Add(new InlineStorageFilter<TPart> { OnSaved = handler });
|
||||||
|
}
|
||||||
|
|
||||||
protected void OnLoading<TPart>(Action<LoadContentContext, TPart> handler) where TPart : class, IContent {
|
protected void OnLoading<TPart>(Action<LoadContentContext, TPart> handler) where TPart : class, IContent {
|
||||||
Filters.Add(new InlineStorageFilter<TPart> { OnLoading = handler });
|
Filters.Add(new InlineStorageFilter<TPart> { OnLoading = handler });
|
||||||
}
|
}
|
||||||
@@ -84,6 +92,8 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
public Action<ActivatedContentContext, TPart> OnActivated { get; set; }
|
public Action<ActivatedContentContext, TPart> OnActivated { get; set; }
|
||||||
public Action<CreateContentContext, TPart> OnCreating { get; set; }
|
public Action<CreateContentContext, TPart> OnCreating { get; set; }
|
||||||
public Action<CreateContentContext, TPart> OnCreated { get; set; }
|
public Action<CreateContentContext, TPart> OnCreated { get; set; }
|
||||||
|
public Action<SaveContentContext, TPart> OnSaving { get; set; }
|
||||||
|
public Action<SaveContentContext, TPart> OnSaved { get; set; }
|
||||||
public Action<LoadContentContext, TPart> OnLoading { get; set; }
|
public Action<LoadContentContext, TPart> OnLoading { get; set; }
|
||||||
public Action<LoadContentContext, TPart> OnLoaded { get; set; }
|
public Action<LoadContentContext, TPart> OnLoaded { get; set; }
|
||||||
public Action<VersionContentContext, TPart, TPart> OnVersioning { get; set; }
|
public Action<VersionContentContext, TPart, TPart> OnVersioning { get; set; }
|
||||||
@@ -103,6 +113,12 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
protected override void Created(CreateContentContext context, TPart instance) {
|
protected override void Created(CreateContentContext context, TPart instance) {
|
||||||
if (OnCreated != null) OnCreated(context, instance);
|
if (OnCreated != null) OnCreated(context, instance);
|
||||||
}
|
}
|
||||||
|
protected override void Saving(SaveContentContext context, TPart instance) {
|
||||||
|
if (OnSaving != null) OnSaving(context, instance);
|
||||||
|
}
|
||||||
|
protected override void Saved(SaveContentContext context, TPart instance) {
|
||||||
|
if (OnSaved != null) OnSaved(context, instance);
|
||||||
|
}
|
||||||
protected override void Loading(LoadContentContext context, TPart instance) {
|
protected override void Loading(LoadContentContext context, TPart instance) {
|
||||||
if (OnLoading != null) OnLoading(context, instance);
|
if (OnLoading != null) OnLoading(context, instance);
|
||||||
}
|
}
|
||||||
@@ -185,6 +201,18 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
Created(context);
|
Created(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IContentHandler.Saving(SaveContentContext context) {
|
||||||
|
foreach (var filter in Filters.OfType<IContentStorageFilter>())
|
||||||
|
filter.Saving(context);
|
||||||
|
Saving(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IContentHandler.Saved(SaveContentContext context) {
|
||||||
|
foreach (var filter in Filters.OfType<IContentStorageFilter>())
|
||||||
|
filter.Saved(context);
|
||||||
|
Saved(context);
|
||||||
|
}
|
||||||
|
|
||||||
void IContentHandler.Loading(LoadContentContext context) {
|
void IContentHandler.Loading(LoadContentContext context) {
|
||||||
foreach (var filter in Filters.OfType<IContentStorageFilter>())
|
foreach (var filter in Filters.OfType<IContentStorageFilter>())
|
||||||
filter.Loading(context);
|
filter.Loading(context);
|
||||||
@@ -272,6 +300,9 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
protected virtual void Creating(CreateContentContext context) { }
|
protected virtual void Creating(CreateContentContext context) { }
|
||||||
protected virtual void Created(CreateContentContext context) { }
|
protected virtual void Created(CreateContentContext context) { }
|
||||||
|
|
||||||
|
protected virtual void Saving(SaveContentContext context) { }
|
||||||
|
protected virtual void Saved(SaveContentContext context) { }
|
||||||
|
|
||||||
protected virtual void Loading(LoadContentContext context) { }
|
protected virtual void Loading(LoadContentContext context) { }
|
||||||
protected virtual void Loaded(LoadContentContext context) { }
|
protected virtual void Loaded(LoadContentContext context) { }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Orchard.ContentManagement.Handlers {
|
namespace Orchard.ContentManagement.Handlers {
|
||||||
@@ -20,6 +19,12 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
public virtual void Created(CreateContentContext context) {
|
public virtual void Created(CreateContentContext context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Saving(SaveContentContext context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Saved(SaveContentContext context) {
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Loading(LoadContentContext context) {
|
public virtual void Loading(LoadContentContext context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Orchard.Events;
|
|
||||||
|
|
||||||
namespace Orchard.ContentManagement.Handlers {
|
namespace Orchard.ContentManagement.Handlers {
|
||||||
public interface IContentHandler : IEvents {
|
public interface IContentHandler : IEvents {
|
||||||
@@ -10,6 +8,8 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
void Activated(ActivatedContentContext context);
|
void Activated(ActivatedContentContext context);
|
||||||
void Creating(CreateContentContext context);
|
void Creating(CreateContentContext context);
|
||||||
void Created(CreateContentContext context);
|
void Created(CreateContentContext context);
|
||||||
|
void Saving(SaveContentContext context);
|
||||||
|
void Saved(SaveContentContext context);
|
||||||
void Loading(LoadContentContext context);
|
void Loading(LoadContentContext context);
|
||||||
void Loaded(LoadContentContext context);
|
void Loaded(LoadContentContext context);
|
||||||
void Versioning(VersionContentContext context);
|
void Versioning(VersionContentContext context);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
void Activated(ActivatedContentContext context);
|
void Activated(ActivatedContentContext context);
|
||||||
void Creating(CreateContentContext context);
|
void Creating(CreateContentContext context);
|
||||||
void Created(CreateContentContext context);
|
void Created(CreateContentContext context);
|
||||||
|
void Saving(SaveContentContext context);
|
||||||
|
void Saved(SaveContentContext context);
|
||||||
void Loading(LoadContentContext context);
|
void Loading(LoadContentContext context);
|
||||||
void Loaded(LoadContentContext context);
|
void Loaded(LoadContentContext context);
|
||||||
void Versioning(VersionContentContext context);
|
void Versioning(VersionContentContext context);
|
||||||
|
|||||||
12
src/Orchard/ContentManagement/Handlers/SaveContentContext.cs
Normal file
12
src/Orchard/ContentManagement/Handlers/SaveContentContext.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Orchard.ContentManagement.Records;
|
||||||
|
|
||||||
|
namespace Orchard.ContentManagement.Handlers {
|
||||||
|
public class SaveContentContext : ContentContextBase {
|
||||||
|
public SaveContentContext(ContentItem contentItem)
|
||||||
|
: base(contentItem) {
|
||||||
|
ContentItemVersionRecord = contentItem.VersionRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentItemVersionRecord ContentItemVersionRecord { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
protected virtual void Activated(ActivatedContentContext context, TPart instance) { }
|
protected virtual void Activated(ActivatedContentContext context, TPart instance) { }
|
||||||
protected virtual void Creating(CreateContentContext context, TPart instance) { }
|
protected virtual void Creating(CreateContentContext context, TPart instance) { }
|
||||||
protected virtual void Created(CreateContentContext context, TPart instance) { }
|
protected virtual void Created(CreateContentContext context, TPart instance) { }
|
||||||
|
protected virtual void Saving(SaveContentContext context, TPart instance) { }
|
||||||
|
protected virtual void Saved(SaveContentContext context, TPart instance) { }
|
||||||
protected virtual void Loading(LoadContentContext context, TPart instance) { }
|
protected virtual void Loading(LoadContentContext context, TPart instance) { }
|
||||||
protected virtual void Loaded(LoadContentContext context, TPart instance) { }
|
protected virtual void Loaded(LoadContentContext context, TPart instance) { }
|
||||||
protected virtual void Versioning(VersionContentContext context, TPart existing, TPart building) { }
|
protected virtual void Versioning(VersionContentContext context, TPart existing, TPart building) { }
|
||||||
@@ -31,6 +33,16 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
Created(context, context.ContentItem.As<TPart>());
|
Created(context, context.ContentItem.As<TPart>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IContentStorageFilter.Saving(SaveContentContext context) {
|
||||||
|
if (context.ContentItem.Is<TPart>())
|
||||||
|
Saving(context, context.ContentItem.As<TPart>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IContentStorageFilter.Saved(SaveContentContext context) {
|
||||||
|
if (context.ContentItem.Is<TPart>())
|
||||||
|
Saved(context, context.ContentItem.As<TPart>());
|
||||||
|
}
|
||||||
|
|
||||||
void IContentStorageFilter.Loading(LoadContentContext context) {
|
void IContentStorageFilter.Loading(LoadContentContext context) {
|
||||||
if (context.ContentItem.Is<TPart>())
|
if (context.ContentItem.Is<TPart>())
|
||||||
Loading(context, context.ContentItem.As<TPart>());
|
Loading(context, context.ContentItem.As<TPart>());
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Orchard.Utility.Extensions;
|
using Orchard.Utility.Extensions;
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,9 @@
|
|||||||
<Compile Include="ContentManagement\Drivers\CombinedResult.cs">
|
<Compile Include="ContentManagement\Drivers\CombinedResult.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ContentManagement\Drivers\ContentFieldDriver.cs" />
|
||||||
|
<Compile Include="ContentManagement\Drivers\ContentFieldDriverHandler.cs" />
|
||||||
|
<Compile Include="ContentManagement\Drivers\ContentFieldTemplateResult.cs" />
|
||||||
<Compile Include="ContentManagement\Drivers\ContentItemDriver.cs">
|
<Compile Include="ContentManagement\Drivers\ContentItemDriver.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -255,6 +258,7 @@
|
|||||||
<Compile Include="ContentManagement\Handlers\RemoveContentContext.cs">
|
<Compile Include="ContentManagement\Handlers\RemoveContentContext.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="ContentManagement\Handlers\SaveContentContext.cs" />
|
||||||
<Compile Include="ContentManagement\Handlers\StorageFilter.cs">
|
<Compile Include="ContentManagement\Handlers\StorageFilter.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
Reference in New Issue
Block a user