Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0

Conflicts:
	src/Umbraco.Web.UI.Client/src/routes.js
This commit is contained in:
Per Ploug Krogslund
2013-08-14 14:30:23 +02:00
88 changed files with 1497 additions and 1520 deletions
+4 -1
View File
@@ -293,7 +293,10 @@ namespace Umbraco.Core.Models
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
{
return (TPassType)Properties[propertyTypeAlias].Value;
if (Properties[propertyTypeAlias].Value is TPassType)
return (TPassType)Properties[propertyTypeAlias].Value;
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
}
/// <summary>
@@ -78,6 +78,53 @@ namespace Umbraco.Core.Models
return (propertyValueChanged && publishedState == PublishedState.Published) || contentDataChanged;
}
/// <summary>
/// Determines if the published db flag should be set to true for the current entity version and all other db
/// versions should have their flag set to false.
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
/// <remarks>
/// This is determined by:
/// * If a new version is being created and the entity is published
/// * If the published state has changed and the entity is published OR the entity has been un-published.
/// </remarks>
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity)
{
var publishedState = ((Content)entity).PublishedState;
return entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, entity.ShouldCreateNewVersion(publishedState));
}
/// <summary>
/// Determines if the published db flag should be set to true for the current entity version and all other db
/// versions should have their flag set to false.
/// </summary>
/// <param name="entity"></param>
/// <param name="publishedState"></param>
/// <param name="isCreatingNewVersion"></param>
/// <returns></returns>
/// <remarks>
/// This is determined by:
/// * If a new version is being created and the entity is published
/// * If the published state has changed and the entity is published OR the entity has been un-published.
/// </remarks>
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity, PublishedState publishedState, bool isCreatingNewVersion)
{
if (isCreatingNewVersion && entity.Published)
{
return true;
}
//If Published state has changed then previous versions should have their publish state reset.
//If state has been changed to unpublished the previous versions publish state should also be reset.
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
{
return true;
}
return false;
}
/// <summary>
/// Returns a list of the current contents ancestors, not including the content itself.
/// </summary>
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents the pre-value data for a DataType
/// </summary>
/// <remarks>
/// Due to the legacy nature of the data that can be stored for pre-values, we have this class which encapsulates the 2 different
/// ways that pre-values are stored: A string array or a Dictionary.
///
/// Most legacy property editors won't support the dictionary format but new property editors should always use the dictionary format.
/// In order to get overrideable pre-values working we need a dictionary since we'll have to reference a pre-value by a key.
/// </remarks>
public class PreValueCollection
{
private IDictionary<string, object> _preValuesAsDictionary;
private IEnumerable<string> _preValuesAsArray;
public IEnumerable<string> PreValuesAsArray
{
get
{
if (_preValuesAsArray == null)
{
throw new InvalidOperationException("The current pre-value collection is dictionary based, use the PreValuesAsDictionary property instead");
}
return _preValuesAsArray;
}
set { _preValuesAsArray = value; }
}
public IDictionary<string, object> PreValuesAsDictionary
{
get
{
if (_preValuesAsDictionary == null)
{
throw new InvalidOperationException("The current pre-value collection is array based, use the PreValuesAsArray property instead");
}
return _preValuesAsDictionary;
}
set { _preValuesAsDictionary = value; }
}
/// <summary>
/// Check if it is a dictionary based collection
/// </summary>
public bool IsDictionaryBased
{
get { return _preValuesAsDictionary != null; }
}
public PreValueCollection(IEnumerable<string> preVals)
{
_preValuesAsArray = preVals;
}
public PreValueCollection(IDictionary<string, object> preVals)
{
_preValuesAsDictionary = preVals;
}
}
}
@@ -64,8 +64,15 @@ namespace Umbraco.Core.Models
}
else
{
var dt = (DateTime)property.Value;
xmlNode.AppendChild(xd.CreateTextNode(dt.ToXmlString<DateTime>()));
var date = property.Value.TryConvertTo<DateTime?>();
if (date.Success == false || date.Result == null)
{
xmlNode.AppendChild(xd.CreateTextNode(string.Empty));
}
else
{
xmlNode.AppendChild(xd.CreateTextNode(date.Result.ToXmlString<DateTime>()));
}
}
break;
default:
+8 -1
View File
@@ -77,7 +77,14 @@ namespace Umbraco.Core
/// <returns></returns>
public static Attempt<object> TryConvertTo(this object input, Type destinationType)
{
if (input == null) return Attempt<object>.False;
//if it is null and it is nullable, then return success with null
if (input == null && destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof (Nullable<>))
{
return new Attempt<object>(true, null);
}
//if its not nullable then return false
if (input == null) return Attempt<object>.False;
if (destinationType == typeof(object)) return new Attempt<object>(true, input);
+18 -12
View File
@@ -13,8 +13,9 @@ namespace Umbraco.Core.ObjectResolution
internal static class Resolution
{
private static readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private volatile static bool _isFrozen;
/// <summary>
/// <summary>
/// Occurs when resolution is frozen.
/// </summary>
/// <remarks>Occurs only once, since resolution can be frozen only once.</remarks>
@@ -23,12 +24,17 @@ namespace Umbraco.Core.ObjectResolution
/// <summary>
/// Gets or sets a value indicating whether resolution of objects is frozen.
/// </summary>
public static bool IsFrozen { get; private set; }
public static void EnsureIsFrozen()
public static bool IsFrozen
{
if (!IsFrozen)
get { return _isFrozen; }
private set { _isFrozen = value; }
}
public static void EnsureIsFrozen()
{
if (!_isFrozen)
throw new InvalidOperationException("Resolution is not frozen, it is not yet possible to get values from it.");
}
/// <summary>
@@ -40,7 +46,7 @@ namespace Umbraco.Core.ObjectResolution
get
{
IDisposable l = new WriteLock(_lock);
if (Resolution.IsFrozen)
if (_isFrozen)
{
l.Dispose();
throw new InvalidOperationException("Resolution is frozen, it is not possible to configure it anymore.");
@@ -73,13 +79,13 @@ namespace Umbraco.Core.ObjectResolution
public DirtyBackdoor()
{
_lock = new WriteLock(_dirtyLock);
_frozen = Resolution.IsFrozen;
Resolution.IsFrozen = false;
_frozen = _isFrozen;
_isFrozen = false;
}
public void Dispose()
{
Resolution.IsFrozen = _frozen;
_isFrozen = _frozen;
_lock.Dispose();
}
}
@@ -90,10 +96,10 @@ namespace Umbraco.Core.ObjectResolution
/// <exception cref="InvalidOperationException">resolution is already frozen.</exception>
public static void Freeze()
{
if (Resolution.IsFrozen)
if (_isFrozen)
throw new InvalidOperationException("Resolution is frozen. It is not possible to freeze it again.");
IsFrozen = true;
_isFrozen = true;
if (Frozen != null)
Frozen(null, null);
}
@@ -104,7 +110,7 @@ namespace Umbraco.Core.ObjectResolution
/// <remarks>To be used in unit tests.</remarks>
internal static void Reset()
{
IsFrozen = false;
_isFrozen = false;
Frozen = null;
}
}
@@ -223,8 +223,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 4, DataTypeId = -88, ControlId = new Guid(Constants.PropertyEditors.Textbox), DbType = "Nvarchar" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 5, DataTypeId = -89, ControlId = new Guid(Constants.PropertyEditors.TextboxMultiple), DbType = "Ntext" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 6, DataTypeId = -90, ControlId = new Guid(Constants.PropertyEditors.UploadField), DbType = "Nvarchar" });
//Dropdown list
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 12, DataTypeId = -91, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 7, DataTypeId = -92, ControlId = new Guid(Constants.PropertyEditors.NoEdit), DbType = "Nvarchar" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 8, DataTypeId = -36, ControlId = new Guid(Constants.PropertyEditors.DateTime), DbType = "Date" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 9, DataTypeId = -37, ControlId = new Guid(Constants.PropertyEditors.ColorPicker), DbType = "Nvarchar" });
@@ -234,24 +232,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 13, DataTypeId = -41, ControlId = new Guid(Constants.PropertyEditors.Date), DbType = "Date" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 14, DataTypeId = -42, ControlId = new Guid(Constants.PropertyEditors.DropDownList), DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 15, DataTypeId = -43, ControlId = new Guid(Constants.PropertyEditors.CheckBoxList), DbType = "Nvarchar" });
// Fix for rich text editor backwards compatibility -> 83722133-f80c-4273-bdb6-1befaa04a612 TinyMCE DataType
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 22, DataTypeId = -44, ControlId = new Guid("a3776494-0574-4d93-b7de-efdfdec6f2d1"), DbType = "Ntext" });
//Radiobutton list
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 23, DataTypeId = -128, ControlId = new Guid("a52c7c1c-c330-476e-8605-d63d3b84b6a6"), DbType = "Nvarchar" });
//Dropdown list multiple
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 24, DataTypeId = -129, ControlId = new Guid("928639ed-9c73-4028-920c-1e55dbb68783"), DbType = "Nvarchar" });
//Dropdown list
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 25, DataTypeId = -130, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
//Dropdown list
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 26, DataTypeId = -131, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
//Dropdown list
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 27, DataTypeId = -132, ControlId = new Guid("a74ea9c9-8e18-4d2a-8cf6-73c6206c5da6"), DbType = "Nvarchar" });
//No edit
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 28, DataTypeId = -133, ControlId = new Guid("6c738306-4c17-4d88-b9bd-6546f3771597"), DbType = "Ntext" });
//Dropdown list multiple
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 29, DataTypeId = -134, ControlId = new Guid("928639ed-9c73-4028-920c-1e55dbb68783"), DbType = "Nvarchar" });
//Not found - maybe a legacy thing?
//_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 30, DataTypeId = -50, ControlId = new Guid("aaf99bb2-dbbe-444d-a296-185076bf0484"), DbType = "Date" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 16, DataTypeId = 1034, ControlId = new Guid(Constants.PropertyEditors.ContentPicker), DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 17, DataTypeId = 1035, ControlId = new Guid(Constants.PropertyEditors.MediaPicker), DbType = "Integer" });
_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 18, DataTypeId = 1036, ControlId = new Guid(Constants.PropertyEditors.MemberPicker), DbType = "Integer" });
@@ -332,7 +332,8 @@ namespace Umbraco.Core.Persistence.Repositories
//If Published state has changed then previous versions should have their publish state reset.
//If state has been changed to unpublished the previous versions publish state should also be reset.
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
//if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
if (entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, shouldCreateNewVersion))
{
var publishedDocs = Database.Fetch<DocumentDto>("WHERE nodeId = @Id AND published = @IsPublished", new { Id = entity.Id, IsPublished = true });
foreach (var doc in publishedDocs)
@@ -84,7 +84,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId).Append(GetGroupBy(isContent, isMedia));
var sql = GetBaseWhere(GetBase, isContent, isMedia, string.Empty, objectTypeId).Append(GetGroupBy(isContent, isMedia));
var dtos = isMedia
? _work.Database.Fetch<UmbracoEntityDto, UmbracoPropertyDto, UmbracoEntityDto>(
new UmbracoEntityRelator().Map, sql)
@@ -101,7 +101,8 @@ namespace Umbraco.Core.Persistence.Repositories
public virtual IEnumerable<IUmbracoEntity> GetByQuery(IQuery<IUmbracoEntity> query)
{
var sqlClause = GetBase(false, false);
var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query<IUmbracoEntity>) query).WhereClauses()));
var sqlClause = GetBase(false, false, wheres);
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
var sql = translator.Translate().Append(GetGroupBy(false, false));
@@ -117,7 +118,9 @@ namespace Umbraco.Core.Persistence.Repositories
{
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId);
var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query<IUmbracoEntity>)query).WhereClauses()));
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, wheres, objectTypeId);
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
var sql = translator.Translate().Append(GetGroupBy(isContent, isMedia));
@@ -136,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories
#region Sql Statements
protected virtual Sql GetBase(bool isContent, bool isMedia)
protected virtual Sql GetBase(bool isContent, bool isMedia, string additionWhereStatement = "")
{
var columns = new List<object>
{
@@ -187,42 +190,38 @@ namespace Umbraco.Core.Persistence.Repositories
.On("umbracoNode.id = latest.nodeId");
}
/*if (isContent)
{
sql.LeftJoin(
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid" +
" INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId) as property")
.On("umbracoNode.id = property.contentNodeId AND latest.versionId = property.versionId");
}*/
if (isMedia)
{
sql.LeftJoin(
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid" +
" INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId) as property")
"(SELECT contentNodeId, versionId, dataNvarchar, controlId FROM cmsPropertyData " +
"INNER JOIN umbracoNode ON cmsPropertyData.contentNodeId = umbracoNode.id " +
"INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid " +
"INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId "+
"WHERE umbracoNode.nodeObjectType = '" + Constants.ObjectTypes.Media + "'" + additionWhereStatement + ") as property")
.On("umbracoNode.id = property.contentNodeId");
}
return sql;
}
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, Guid id)
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, string additionWhereStatement, Guid id)
{
var sql = baseQuery(isContent, isMedia)
var sql = baseQuery(isContent, isMedia, additionWhereStatement)
.Where("umbracoNode.nodeObjectType = @NodeObjectType", new { NodeObjectType = id });
return sql;
}
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, int id)
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, int id)
{
var sql = baseQuery(isContent, isMedia)
var sql = baseQuery(isContent, isMedia, " AND umbracoNode.id = '"+ id +"'")
.Where("umbracoNode.id = @Id", new { Id = id })
.Append(GetGroupBy(isContent, isMedia));
return sql;
}
protected virtual Sql GetBaseWhere(Func<bool, bool, Sql> baseQuery, bool isContent, bool isMedia, Guid objectId, int id)
protected virtual Sql GetBaseWhere(Func<bool, bool, string, Sql> baseQuery, bool isContent, bool isMedia, Guid objectId, int id)
{
var sql = baseQuery(isContent, isMedia)
var sql = baseQuery(isContent, isMedia, " AND umbracoNode.id = '"+ id +"'")
.Where("umbracoNode.id = @Id AND umbracoNode.nodeObjectType = @NodeObjectType",
new {Id = id, NodeObjectType = objectId});
return sql;
+6 -2
View File
@@ -430,7 +430,9 @@ namespace Umbraco.Core
/// </summary>
internal IEnumerable<Type> ResolvePropertyEditors()
{
return ResolveTypes<PropertyEditor>();
//return all proeprty editor types found except for the base property editor type
return ResolveTypes<PropertyEditor>()
.Except(new[] {typeof (PropertyEditor)});
}
/// <summary>
@@ -466,7 +468,9 @@ namespace Umbraco.Core
/// <returns></returns>
internal IEnumerable<Type> ResolveDataTypes()
{
return ResolveTypes<IDataType>();
//ensure we ignore types that should not be loaded
return ResolveTypes<IDataType>()
.Except(new[] {Type.GetType("umbraco.presentation.LiveEditing.Modules.ItemEditing.PageElementEditor,umbraco")});
}
/// <summary>
@@ -3,6 +3,12 @@ using Newtonsoft.Json;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Defines a pre-value editor
/// </summary>
/// <remarks>
/// The Json serialization attributes are required for manifest property editors to work
/// </remarks>
public class PreValueEditor
{
/// <summary>
@@ -1,9 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
namespace Umbraco.Core.PropertyEditors
{
/// <summary>
/// Basic definition of a property editor
/// </summary>
/// <remarks>
/// The Json serialization attributes are required for manifest property editors to work
/// </remarks>
public class PropertyEditor
{
/// <summary>
@@ -20,14 +29,23 @@ namespace Umbraco.Core.PropertyEditors
{
Id = Guid.Parse(att.Id);
Name = att.Name;
StaticallyDefinedValueEditor.ValueType = att.ValueType;
StaticallyDefinedValueEditor.View = att.EditorView;
StaticallyDefinedPreValueEditor.View = att.PreValueEditorView;
}
}
/// <summary>
/// These are assigned by default normally based on property editor attributes or manifest definitions,
/// developers have the chance to override CreateValueEditor if they don't want to use the pre-defined instance
/// </summary>
internal ValueEditor StaticallyDefinedValueEditor = null;
/// <summary>
/// These are assigned by default normally based on property editor attributes or manifest definitions,
/// developers have the chance to override CreatePreValueEditor if they don't want to use the pre-defined instance
/// </summary>
internal PreValueEditor StaticallyDefinedPreValueEditor = null;
/// <summary>
@@ -54,6 +72,9 @@ namespace Umbraco.Core.PropertyEditors
get { return CreatePreValueEditor(); }
}
[JsonProperty("defaultConfig")]
public virtual IDictionary<string, object> DefaultPreValues { get; set; }
//TODO: Now we need to implement a couple of methods for saving the data for editors and pre-value editors
// generally we can handle that automatically in this base class but people should be allowed to override
// it so they can perform custom operations on saving the data.
@@ -88,6 +109,48 @@ namespace Umbraco.Core.PropertyEditors
return StaticallyDefinedPreValueEditor;
}
/// <summary>
/// This can be used to re-format the currently saved pre-values that will be passed to the editor,
/// by default this returns the merged default and persisted pre-values.
/// </summary>
/// <param name="defaultPreVals">
/// The default/static pre-vals for the property editor
/// </param>
/// <param name="persistedPreVals">
/// The persisted pre-vals for the property editor
/// </param>
/// <returns></returns>
/// <remarks>
/// This is generally not going to be used by anything unless a property editor wants to change the merging
/// functionality or needs to convert some legacy persisted data, or convert the string values to strongly typed values in json (i.e. booleans)
/// </remarks>
public virtual IDictionary<string, object> FormatPreValues(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals)
{
if (defaultPreVals == null)
{
defaultPreVals = new Dictionary<string, object>();
}
if (persistedPreVals.IsDictionaryBased)
{
//we just need to merge the dictionaries now, the persisted will replace default.
foreach (var item in persistedPreVals.PreValuesAsDictionary)
{
defaultPreVals[item.Key] = item.Value;
}
return defaultPreVals;
}
//it's an array so need to format it
var result = new Dictionary<string, object>();
var asArray = persistedPreVals.PreValuesAsArray.ToArray();
for (var i = 0; i < asArray.Length; i++)
{
result.Add(i.ToInvariantString(), asArray[i]);
}
return result;
}
protected bool Equals(PropertyEditor other)
{
return Id.Equals(other.Id);
@@ -10,6 +10,9 @@ namespace Umbraco.Core.PropertyEditors
/// <summary>
/// Represents the value editor for the property editor during content editing
/// </summary>
/// <remarks>
/// The Json serialization attributes are required for manifest property editors to work
/// </remarks>
public class ValueEditor
{
/// <summary>
@@ -126,10 +129,12 @@ namespace Umbraco.Core.PropertyEditors
valueType = typeof(string);
break;
case DataTypeDatabaseType.Integer:
valueType = typeof(int);
//ensure these are nullable so we can return a null if required
valueType = typeof(int?);
break;
case DataTypeDatabaseType.Date:
valueType = typeof(DateTime);
//ensure these are nullable so we can return a null if required
valueType = typeof(DateTime?);
break;
default:
throw new ArgumentOutOfRangeException();
@@ -180,9 +185,14 @@ namespace Umbraco.Core.PropertyEditors
case DataTypeDatabaseType.Integer:
//we can just ToString() any of these types
return dbValue.ToString();
case DataTypeDatabaseType.Date:
//Dates will be formatted in 'o' format (otherwise known as xml format)
return dbValue.ToXmlString<DateTime>();
case DataTypeDatabaseType.Date:
var date = dbValue.TryConvertTo<DateTime?>();
if (date.Success == false || date.Result == null)
{
return string.Empty;
}
//Dates will be formatted as yyyy-MM-dd HH:mm:ss
return date.Result.Value.ToIsoString();
default:
throw new ArgumentOutOfRangeException();
}
@@ -133,6 +133,22 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Returns the PreValueCollection for the specified data type
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
internal PreValueCollection GetPreValuesCollectionByDataTypeId(int id)
{
using (var uow = _uowProvider.GetUnitOfWork())
{
var dtos = uow.Database.Fetch<DataTypePreValueDto>("WHERE datatypeNodeId = @Id", new { Id = id });
var list = dtos.Select(x => new Tuple<int, string, int, string>(x.Id, x.Alias, x.SortOrder, x.Value)).ToList();
return PreValueConverter.ConvertToPreValuesCollection(list);
}
}
/// <summary>
/// Gets a specific PreValue by its Id
/// </summary>
@@ -327,5 +343,41 @@ namespace Umbraco.Core.Services
/// </summary>
public static event TypedEventHandler<IDataTypeService, SaveEventArgs<IDataTypeDefinition>> Saved;
#endregion
internal static class PreValueConverter
{
/// <summary>
/// Converts the tuple to a pre-value collection
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
internal static PreValueCollection ConvertToPreValuesCollection(IEnumerable<Tuple<int, string, int, string>> list)
{
//now we need to determine if they are dictionary based, otherwise they have to be array based
var dictionary = new Dictionary<string, object>();
//need to check all of the keys, if there's only one and it is empty then it's an array
var keys = list.Select(x => x.Item2).Distinct().ToArray();
if (keys.Length == 1 && keys[0].IsNullOrWhiteSpace())
{
return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item4));
}
foreach (var item in list
.OrderBy(x => x.Item3) //we'll order them first so we maintain the order index in the dictionary
.GroupBy(x => x.Item2))
{
if (item.Count() > 1)
{
//if there's more than 1 item per key, then it cannot be a dictionary, just return the array
return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item4));
}
dictionary.Add(item.Key, item.First().Item4);
}
return new PreValueCollection(dictionary);
}
}
}
}
+10
View File
@@ -28,6 +28,16 @@ namespace Umbraco.Core
[UmbracoWillObsolete("Do not use this constants. See IShortStringHelper.CleanStringForSafeAliasJavaScriptCode.")]
public const string UmbracoInvalidFirstCharacters = "01234567890";
public static string ExceptChars(this string str, HashSet<char> toExclude)
{
var sb = new StringBuilder(str.Length);
foreach (var c in str.Where(c => toExclude.Contains(c) == false))
{
sb.Append(c);
}
return sb.ToString();
}
/// <summary>
/// Returns a stream from a string
/// </summary>
+1
View File
@@ -225,6 +225,7 @@
<Compile Include="Models\Mapping\MapperConfiguration.cs" />
<Compile Include="Models\Membership\EntityPermission.cs" />
<Compile Include="Models\Membership\UmbracoMembershipUser.cs" />
<Compile Include="Models\PreValueCollection.cs" />
<Compile Include="Models\ServerRegistration.cs" />
<Compile Include="Models\ITemplate.cs" />
<Compile Include="Models\Language.cs" />
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using NUnit.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Tests.AngularIntegration
@@ -29,7 +30,7 @@ namespace Umbraco.Tests.AngularIntegration
Label = "Property " + propertyIndex,
Id = propertyIndex,
Value = "value" + propertyIndex,
Config = new[] {"config" + propertyIndex},
Config = new Dictionary<string, string> {{ propertyIndex.ToInvariantString(), "value" }},
Description = "Description " + propertyIndex,
View = "~/Views/View" + propertyIndex,
HideLabel = false
@@ -68,7 +69,7 @@ namespace Umbraco.Tests.AngularIntegration
Assert.AreEqual("Property " + prop, jObject["tabs"][tab]["properties"][prop]["label"].ToString());
Assert.AreEqual(prop, jObject["tabs"][tab]["properties"][prop]["id"].Value<int>());
Assert.AreEqual("value" + prop, jObject["tabs"][tab]["properties"][prop]["value"].ToString());
Assert.AreEqual("[\"config" + prop + "\"]", jObject["tabs"][tab]["properties"][prop]["config"].ToString(Formatting.None));
Assert.AreEqual("{\"" + prop + "\":\"value\"}", jObject["tabs"][tab]["properties"][prop]["config"].ToString(Formatting.None));
Assert.AreEqual("Description " + prop, jObject["tabs"][tab]["properties"][prop]["description"].ToString());
Assert.AreEqual(false, jObject["tabs"][tab]["properties"][prop]["hideLabel"].Value<bool>());
}
@@ -82,6 +82,61 @@ namespace Umbraco.Tests.Models
}
[Test]
public void Should_Clear_Published_Flag_When_Newly_Published_Version()
{
var contentType = MockedContentTypes.CreateTextpageContentType();
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Published);
Assert.IsTrue(content.ShouldClearPublishedFlagForPreviousVersions());
}
[Test]
public void Should_Not_Clear_Published_Flag_When_Saving_Version()
{
var contentType = MockedContentTypes.CreateTextpageContentType();
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Published);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Saved);
Assert.IsFalse(content.ShouldClearPublishedFlagForPreviousVersions());
}
[Test]
public void Should_Clear_Published_Flag_When_Unpublishing_From_Published()
{
var contentType = MockedContentTypes.CreateTextpageContentType();
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Published);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Unpublished);
Assert.IsTrue(content.ShouldClearPublishedFlagForPreviousVersions());
}
[Test]
public void Should_Not_Clear_Published_Flag_When_Unpublishing_From_Saved()
{
var contentType = MockedContentTypes.CreateTextpageContentType();
var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Saved);
content.ResetDirtyProperties(false);
content.ChangePublishedState(PublishedState.Unpublished);
Assert.IsFalse(content.ShouldClearPublishedFlagForPreviousVersions());
}
}
}
@@ -31,8 +31,8 @@ namespace Umbraco.Tests.Models.Mapping
protected override void FreezeResolution()
{
PropertyEditorResolver.Current = new PropertyEditorResolver(
() => new List<Type> {typeof (TestPropertyEditor)});
//PropertyEditorResolver.Current = new PropertyEditorResolver(
// () => new List<Type> {typeof (TestPropertyEditor)});
base.FreezeResolution();
}
@@ -96,6 +96,13 @@ namespace Umbraco.Tests.Models.Mapping
{
var contentType = MockedContentTypes.CreateSimpleContentType();
var content = MockedContent.CreateSimpleContent(contentType);
//need ids for tabs
var id = 1;
foreach (var g in content.PropertyGroups)
{
g.Id = id;
id++;
}
var result = Mapper.Map<IContent, ContentItemDisplay>(content);
@@ -131,6 +138,13 @@ namespace Umbraco.Tests.Models.Mapping
p.Id = idSeed;
idSeed++;
}
//need ids for tabs
var id = 1;
foreach (var g in content.PropertyGroups)
{
g.Id = id;
id++;
}
//ensure that nothing is marked as dirty
contentType.ResetDirtyProperties(false);
//ensure that nothing is marked as dirty
@@ -145,7 +159,7 @@ namespace Umbraco.Tests.Models.Mapping
}
Assert.AreEqual(content.PropertyGroups.Count(), result.Tabs.Count() - 1);
Assert.IsTrue(result.Tabs.Any(x => x.Label == "Generic properties"));
Assert.AreEqual(2, result.Tabs.Where(x => x.Label == "Generic properties").SelectMany(x => x.Properties).Count());
Assert.AreEqual(2, result.Tabs.Where(x => x.Label == "Generic properties").SelectMany(x => x.Properties.Where(p => p.Alias.StartsWith("_umb_") == false)).Count());
}
#region Assertions
@@ -158,10 +172,11 @@ namespace Umbraco.Tests.Models.Mapping
var pDto = result.Properties.SingleOrDefault(x => x.Alias == p.Alias);
Assert.IsNotNull(pDto);
pDto.Alias = p.Alias;
pDto.Description = p.PropertyType.Description;
pDto.Label = p.PropertyType.Name;
pDto.Config = applicationContext.Services.DataTypeService.GetPreValuesByDataTypeId(p.PropertyType.DataTypeDefinitionId);
//pDto.Alias = p.Alias;
//pDto.Description = p.PropertyType.Description;
//pDto.Label = p.PropertyType.Name;
//pDto.Config = applicationContext.Services.DataTypeService.GetPreValuesByDataTypeId(p.PropertyType.DataTypeDefinitionId);
}
@@ -176,7 +191,7 @@ namespace Umbraco.Tests.Models.Mapping
Assert.AreEqual(content.UpdateDate, result.UpdateDate);
Assert.AreEqual(content.CreateDate, result.CreateDate);
Assert.AreEqual(content.Name, result.Name);
Assert.AreEqual(content.Properties.Count(), result.Properties.Count());
Assert.AreEqual(content.Properties.Count(), result.Properties.Count(x => x.Alias.StartsWith("_umb_") == false));
}
private void AssertBasicProperty<T, TPersisted>(ContentItemBasic<T, TPersisted> result, Property p)
@@ -1,13 +1,12 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.PropertyEditors
{
[TestFixture]
[TestFixture]
public class PropertyEditorValueConverterTests
{
[TestCase("2012-11-10", true)]
@@ -0,0 +1,72 @@
using System;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Tests.PropertyEditors
{
[TestFixture]
public class PropertyEditorValueEditorTests
{
[TestCase("STRING", "hello", "hello")]
[TestCase("TEXT", "hello", "hello")]
[TestCase("INT", "123", 123)]
[TestCase("INTEGER", "123", 123)]
[TestCase("INTEGER", "", null)] //test empty string for int
[TestCase("DATETIME", "", null)] //test empty string for date
public void Value_Editor_Can_Convert_To_Clr_Type(string valueType, string val, object expected)
{
var valueEditor = new ValueEditor
{
ValueType = valueType
};
var result = valueEditor.TryConvertValueToCrlType(val);
Assert.IsTrue(result.Success);
Assert.AreEqual(expected, result.Result);
}
[Test]
public void Value_Editor_Can_Convert_To_Date_Clr_Type()
{
var valueEditor = new ValueEditor
{
ValueType = "DATE"
};
var result = valueEditor.TryConvertValueToCrlType("2010-02-05");
Assert.IsTrue(result.Success);
Assert.AreEqual(new DateTime(2010, 2, 5), result.Result);
}
[TestCase("STRING", "hello", "hello")]
[TestCase("TEXT", "hello", "hello")]
[TestCase("INT", 123, "123")]
[TestCase("INTEGER", 123, "123")]
[TestCase("INTEGER", "", "")] //test empty string for int
[TestCase("DATETIME", "", "")] //test empty string for date
public void Value_Editor_Can_Serialize_Value(string valueType, object val, string expected)
{
var valueEditor = new ValueEditor
{
ValueType = valueType
};
var result = valueEditor.SerializeValue(val);
Assert.AreEqual(expected, result);
}
[Test]
public void Value_Editor_Can_Serialize_Date_Value()
{
var now = DateTime.Now;
var valueEditor = new ValueEditor
{
ValueType = "DATE"
};
var result = valueEditor.SerializeValue(now);
Assert.AreEqual(now.ToXmlString<DateTime>(), result);
}
}
}
@@ -813,6 +813,48 @@ namespace Umbraco.Tests.Services
Assert.That(hasPublishedVersion, Is.True);
}
[Test]
public void Can_Verify_Property_Types_On_Content()
{
// Arrange
var contentTypeService = ServiceContext.ContentTypeService;
var contentType = MockedContentTypes.CreateAllTypesContentType("allDataTypes", "All DataTypes");
contentTypeService.Save(contentType);
var contentService = ServiceContext.ContentService;
var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", -1);
contentService.Save(content);
var id = content.Id;
// Act
var sut = contentService.GetById(id);
// Arrange
Assert.That(sut.GetValue<bool>("isTrue"), Is.True);
Assert.That(sut.GetValue<int>("number"), Is.EqualTo(42));
Assert.That(sut.GetValue<string>("bodyText"), Is.EqualTo("Lorem Ipsum Body Text Test"));
Assert.That(sut.GetValue<string>("singleLineText"), Is.EqualTo("Single Line Text Test"));
Assert.That(sut.GetValue<string>("multilineText"), Is.EqualTo("Multiple lines \n in one box"));
Assert.That(sut.GetValue<string>("upload"), Is.EqualTo("/media/1234/koala.jpg"));
Assert.That(sut.GetValue<string>("label"), Is.EqualTo("Non-editable label"));
Assert.That(sut.GetValue<DateTime>("dateTime"), Is.EqualTo(content.GetValue<DateTime>("dateTime")));
Assert.That(sut.GetValue<string>("colorPicker"), Is.EqualTo("black"));
Assert.That(sut.GetValue<string>("folderBrowser"), Is.Empty);
Assert.That(sut.GetValue<string>("ddlMultiple"), Is.EqualTo("1234,1235"));
Assert.That(sut.GetValue<string>("rbList"), Is.EqualTo("random"));
Assert.That(sut.GetValue<DateTime>("date"), Is.EqualTo(content.GetValue<DateTime>("date")));
Assert.That(sut.GetValue<string>("ddl"), Is.EqualTo("1234"));
Assert.That(sut.GetValue<string>("chklist"), Is.EqualTo("randomc"));
Assert.That(sut.GetValue<int>("contentPicker"), Is.EqualTo(1090));
Assert.That(sut.GetValue<int>("mediaPicker"), Is.EqualTo(1091));
Assert.That(sut.GetValue<int>("memberPicker"), Is.EqualTo(1092));
Assert.That(sut.GetValue<string>("simpleEditor"), Is.EqualTo("This is simply edited"));
Assert.That(sut.GetValue<string>("ultimatePicker"), Is.EqualTo("1234,1235"));
Assert.That(sut.GetValue<string>("relatedLinks"), Is.EqualTo("<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>"));
Assert.That(sut.GetValue<string>("tags"), Is.EqualTo("this,is,tags"));
Assert.That(sut.GetValue<string>("macroContainer"), Is.Empty);
Assert.That(sut.GetValue<string>("imgCropper"), Is.Empty);
}
private IEnumerable<IContent> CreateContentHierarchy()
{
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
@@ -23,6 +23,8 @@ namespace Umbraco.Tests.Services
base.TearDown();
}
[Test]
public void DataTypeService_Can_Persist_New_DataTypeDefinition()
{
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core.Services;
namespace Umbraco.Tests.Services
{
[TestFixture]
public class PreValueConverterTests
{
[Test]
public void Can_Convert_To_Dictionary_Pre_Value_Collection()
{
var list = new List<Tuple<int, string, int, string>>
{
new Tuple<int, string, int, string>(10, "key1", 0, "value1"),
new Tuple<int, string, int, string>(11, "key2", 3, "value2"),
new Tuple<int, string, int, string>(12, "key3", 2, "value3"),
new Tuple<int, string, int, string>(13, "key4", 1, "value4")
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
Assert.Throws<InvalidOperationException>(() =>
{
var blah = result.PreValuesAsArray;
});
Assert.AreEqual(4, result.PreValuesAsDictionary.Count);
Assert.AreEqual("key1", result.PreValuesAsDictionary.ElementAt(0).Key);
Assert.AreEqual("key4", result.PreValuesAsDictionary.ElementAt(1).Key);
Assert.AreEqual("key3", result.PreValuesAsDictionary.ElementAt(2).Key);
Assert.AreEqual("key2", result.PreValuesAsDictionary.ElementAt(3).Key);
}
[Test]
public void Can_Convert_To_Array_Pre_Value_Collection_When_Empty_Key()
{
var list = new List<Tuple<int, string, int, string>>
{
new Tuple<int, string, int, string>(10, "", 0, "value1"),
new Tuple<int, string, int, string>(11, "", 3, "value2"),
new Tuple<int, string, int, string>(12, "", 2, "value3"),
new Tuple<int, string, int, string>(13, "", 1, "value4")
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
Assert.Throws<InvalidOperationException>(() =>
{
var blah = result.PreValuesAsDictionary;
});
Assert.AreEqual(4, result.PreValuesAsArray.Count());
Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0));
Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1));
Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2));
Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3));
}
[Test]
public void Can_Convert_To_Array_Pre_Value_Collection()
{
var list = new List<Tuple<int, string, int, string>>
{
new Tuple<int, string, int, string>(10, "key1", 0, "value1"),
new Tuple<int, string, int, string>(11, "key1", 3, "value2"),
new Tuple<int, string, int, string>(12, "key3", 2, "value3"),
new Tuple<int, string, int, string>(13, "key4", 1, "value4")
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
Assert.Throws<InvalidOperationException>(() =>
{
var blah = result.PreValuesAsDictionary;
});
Assert.AreEqual(4, result.PreValuesAsArray.Count());
Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0));
Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1));
Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2));
Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3));
}
}
}
@@ -79,6 +79,38 @@ namespace Umbraco.Tests.TestHelpers.Entities
return content;
}
public static Content CreateAllTypesContent(IContentType contentType, string name, int parentId)
{
var content = new Content("Random Content Name", parentId, contentType) { Language = "en-US", Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
content.SetValue("isTrue", true);
content.SetValue("number", 42);
content.SetValue("bodyText", "Lorem Ipsum Body Text Test");
content.SetValue("singleLineText", "Single Line Text Test");
content.SetValue("multilineText", "Multiple lines \n in one box");
content.SetValue("upload", "/media/1234/koala.jpg");
content.SetValue("label", "Non-editable label");
content.SetValue("dateTime", DateTime.Now.AddDays(-20));
content.SetValue("colorPicker", "black");
content.SetValue("folderBrowser", "");
content.SetValue("ddlMultiple", "1234,1235");
content.SetValue("rbList", "random");
content.SetValue("date", DateTime.Now.AddDays(-10));
content.SetValue("ddl", "1234");
content.SetValue("chklist", "randomc");
content.SetValue("contentPicker", 1090);
content.SetValue("mediaPicker", 1091);
content.SetValue("memberPicker", 1092);
content.SetValue("simpleEditor", "This is simply edited");
content.SetValue("ultimatePicker", "1234,1235");
content.SetValue("relatedLinks", "<links><link title=\"google\" link=\"http://google.com\" type=\"external\" newwindow=\"0\" /></links>");
content.SetValue("tags", "this,is,tags");
content.SetValue("macroContainer", "");
content.SetValue("imgCropper", "");
return content;
}
public static IEnumerable<Content> CreateTextpageContent(IContentType contentType, int parentId, int amount)
{
var list = new List<Content>();
@@ -180,6 +180,51 @@ namespace Umbraco.Tests.TestHelpers.Entities
return contentType;
}
public static ContentType CreateAllTypesContentType(string alias, string name)
{
var contentType = new ContentType(-1)
{
Alias = alias,
Name = name,
Description = "ContentType containing all standard DataTypes",
Icon = ".sprTreeDoc3",
Thumbnail = "doc.png",
SortOrder = 1,
CreatorId = 0,
Trashed = false
};
var contentCollection = new PropertyTypeCollection();
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer) { Alias = "isTrue", Name = "Is True or False", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -49 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Integer), DataTypeDatabaseType.Integer) { Alias = "number", Name = "Number", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -51 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TinyMCEv3), DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -87 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar) { Alias = "singleLineText", Name = "Text String", Mandatory = false, SortOrder = 4, DataTypeDefinitionId = -88 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext) { Alias = "multilineText", Name = "Multiple Text Strings", Mandatory = false, SortOrder = 5, DataTypeDefinitionId = -89 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UploadField), DataTypeDatabaseType.Nvarchar) { Alias = "upload", Name = "Upload Field", Mandatory = false, SortOrder = 6, DataTypeDefinitionId = -90 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar) { Alias = "label", Name = "Label", Mandatory = false, SortOrder = 7, DataTypeDefinitionId = -92 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DateTime), DataTypeDatabaseType.Date) { Alias = "dateTime", Name = "Date Time", Mandatory = false, SortOrder = 8, DataTypeDefinitionId = -36 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ColorPicker), DataTypeDatabaseType.Nvarchar) { Alias = "colorPicker", Name = "Color Picker", Mandatory = false, SortOrder = 9, DataTypeDefinitionId = -37 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.FolderBrowser), DataTypeDatabaseType.Nvarchar) { Alias = "folderBrowser", Name = "Folder Browser", Mandatory = false, SortOrder = 10, DataTypeDefinitionId = -38 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DropDownListMultiple), DataTypeDatabaseType.Nvarchar) { Alias = "ddlMultiple", Name = "Dropdown List Multiple", Mandatory = false, SortOrder = 11, DataTypeDefinitionId = -39 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.RadioButtonList), DataTypeDatabaseType.Nvarchar) { Alias = "rbList", Name = "Radio Button List", Mandatory = false, SortOrder = 12, DataTypeDefinitionId = -40 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Date), DataTypeDatabaseType.Date) { Alias = "date", Name = "Date", Mandatory = false, SortOrder = 13, DataTypeDefinitionId = -41 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.DropDownList), DataTypeDatabaseType.Integer) { Alias = "ddl", Name = "Dropdown List", Mandatory = false, SortOrder = 14, DataTypeDefinitionId = -42 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.CheckBoxList), DataTypeDatabaseType.Nvarchar) { Alias = "chklist", Name = "Checkbox List", Mandatory = false, SortOrder = 15, DataTypeDefinitionId = -43 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ContentPicker), DataTypeDatabaseType.Integer) { Alias = "contentPicker", Name = "Content Picker", Mandatory = false, SortOrder = 16, DataTypeDefinitionId = 1034 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MediaPicker), DataTypeDatabaseType.Integer) { Alias = "mediaPicker", Name = "Media Picker", Mandatory = false, SortOrder = 17, DataTypeDefinitionId = 1035 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MemberPicker), DataTypeDatabaseType.Integer) { Alias = "memberPicker", Name = "Member Picker", Mandatory = false, SortOrder = 18, DataTypeDefinitionId = 1036 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UltraSimpleEditor), DataTypeDatabaseType.Ntext) { Alias = "simpleEditor", Name = "Ultra Simple Editor", Mandatory = false, SortOrder = 19, DataTypeDefinitionId = 1038 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.UltimatePicker), DataTypeDatabaseType.Ntext) { Alias = "ultimatePicker", Name = "Ultimate Picker", Mandatory = false, SortOrder = 20, DataTypeDefinitionId = 1039 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.RelatedLinks), DataTypeDatabaseType.Ntext) { Alias = "relatedLinks", Name = "Related Links", Mandatory = false, SortOrder = 21, DataTypeDefinitionId = 1040 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.Tags), DataTypeDatabaseType.Ntext) { Alias = "tags", Name = "Tags", Mandatory = false, SortOrder = 22, DataTypeDefinitionId = 1041 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.MacroContainer), DataTypeDatabaseType.Ntext) { Alias = "macroContainer", Name = "Macro Container", Mandatory = false, SortOrder = 23, DataTypeDefinitionId = 1042 });
contentCollection.Add(new PropertyType(new Guid(Constants.PropertyEditors.ImageCropper), DataTypeDatabaseType.Ntext) { Alias = "imgCropper", Name = "Image Cropper", Mandatory = false, SortOrder = 24, DataTypeDefinitionId = 1043 });
contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
return contentType;
}
public static MediaType CreateVideoMediaType()
{
var mediaType = new MediaType(-1)
+4 -2
View File
@@ -55,9 +55,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\AutoMapper.2.2.1\lib\net40\AutoMapper.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -213,8 +213,10 @@
<Compile Include="Persistence\Repositories\UserRepositoryTest.cs" />
<Compile Include="Persistence\Repositories\UserTypeRepositoryTest.cs" />
<Compile Include="Models\Mapping\ContentWebModelMappingTests.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueEditorTests.cs" />
<Compile Include="Services\PackagingServiceTests.cs" />
<Compile Include="Services\PerformanceTests.cs" />
<Compile Include="Services\PreValueConverterTests.cs" />
<Compile Include="Services\UserServiceTests.cs" />
<Compile Include="Manifest\ManifestParserTests.cs" />
<Compile Include="TestHelpers\BaseSeleniumTest.cs" />
+1 -1
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AspNetWebApi.SelfHost" version="4.0.20710.0" targetFramework="net45" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="AutoMapper" version="2.2.1" targetFramework="net45" />
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
@@ -5,7 +5,7 @@
/** Converts a Date object to a globally acceptable ISO string, NOTE: This is different from the built in
JavaScript toISOString method which returns date/time like "2013-08-07T02:04:11.487Z" but we want "yyyy-MM-dd HH:mm:ss" */
Date.prototype.toIsoDateTimeString = function (str) {
var month = this.getMonth().toString();
var month = (this.getMonth() + 1).toString();
if (month.length === 1) {
month = "0" + month;
}
@@ -28,6 +28,23 @@
return this.getFullYear() + "-" + month + "-" + day + " " + hour + ":" + mins + ":" + secs;
};
}
if (!Date.prototype.toIsoDateString) {
/** Converts a Date object to a globally acceptable ISO string, NOTE: This is different from the built in
JavaScript toISOString method which returns date/time like "2013-08-07T02:04:11.487Z" but we want "yyyy-MM-dd" */
Date.prototype.toIsoDateString = function (str) {
var month = (this.getMonth() + 1).toString();
if (month.length === 1) {
month = "0" + month;
}
var day = this.getDate().toString();
if (day.length === 1) {
day = "0" + day;
}
return this.getFullYear() + "-" + month + "-" + day;
};
}
//create guid method on the String
if (String.CreateGuid == null) {
@@ -2,6 +2,7 @@
* @ngdoc directive
* @function
* @name umbraco.directives.directive:umbEditor
* @requires formController
* @restrict E
**/
angular.module("umbraco.directives")
@@ -10,11 +11,17 @@ angular.module("umbraco.directives")
scope: {
model: "="
},
require: "^form",
restrict: 'E',
replace: true,
templateUrl: 'views/directives/umb-editor.html',
link: function (scope, element, attrs, ctrl) {
//we need to copy the form controller val to our isolated scope so that
//it get's carried down to the child scopes of this!
//we'll also maintain the current form name.
scope[ctrl.$name] = ctrl;
if(!scope.model.alias){
scope.model.alias = Math.random().toString(36).slice(2);
}
@@ -33,8 +33,8 @@ angular.module("umbraco.directives")
template: '<li><div ng-style="setTreePadding(node)" ng-class="{\'loading\': node.loading}">' +
'<ins ng-hide="node.hasChildren" style="background:none;width:18px;"></ins>' +
'<ins ng-show="node.hasChildren" ng-class="{\'icon-caret-right\': !node.expanded, \'icon-caret-down\': node.expanded}" ng-click="load(this, node)"></ins>' +
'<i class="{{node.cssClass}}" style="{{node.style}}"></i>' +
'<a href title="#{{node.routePath}}" ng-click="select(this, node, $event)" >{{node.name}}</a>' +
'<i title="#{{node.routePath}}" class="{{node.cssClass}}" style="{{node.style}}"></i>' +
'<a href ng-click="select(this, node, $event)" >{{node.name}}</a>' +
'<a href class="umb-options" ng-hide="!node.menuUrl" ng-click="options(this, node, $event)"><i></i><i></i><i></i></a>' +
'<div ng-show="node.loading" class="l"><div></div></div>' +
'</div>' +
@@ -94,7 +94,9 @@ function valPropertyMsg(serverValidationManager) {
// we need to re-validate it for the server side validator so the user can resubmit
// the form. Of course normal client-side validators will continue to execute.
scope.$watch("property.value", function (newValue) {
if (formCtrl.$invalid) {
//we are explicitly checking for valServer errors here, since we shouldn't auto clear
// based on other errors.
if (formCtrl.$invalid && scope.formCtrl.$error.valServer !== undefined) {
scope.errorMsg = "";
formCtrl.$setValidity('valPropertyMsg', true);
}
@@ -30,8 +30,6 @@ function valServer(serverValidationManager) {
ctrl.$viewChangeListeners.push(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServer', true);
//emit the event upwards
scope.$emit("serverRevalidated", { modelCtrl: ctrl });
}
});
@@ -25,8 +25,6 @@ function valServerField(serverValidationManager) {
ctrl.$viewChangeListeners.push(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServerField', true);
//emit the event upwards
scope.$emit("serverRevalidated", { modelCtrl: ctrl });
}
});
@@ -13,6 +13,7 @@ function valTab() {
var tabId = "tab" + scope.tab.id;
//assign the form control to our isolated scope so we can watch it's values
scope.formCtrl = formCtrl;
scope.tabHasError = false;
@@ -15,10 +15,13 @@ function valToggleMsg(serverValidationManager) {
throw "valToggleMsg requires that the attribute valMsgFor exists on the element";
}
//assign the form control to our isolated scope so we can watch it's values
scope.formCtrl = formCtrl;
//if there's any remaining errors in the server validation service then we should show them.
var showValidation = serverValidationManager.items.length > 0;
var hasError = false;
//add a watch to the validator for the value (i.e. myForm.value.$error.required )
scope.$watch(formCtrl.$name + "." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function (isInvalid, oldValue) {
hasError = isInvalid;
@@ -45,7 +45,7 @@ angular.module('umbraco.mocks').
label: "Sample Editor",
id: 3,
properties: [
{ alias: "datepicker", label: "Datepicker", view: "datepicker", config: { rows: 7 } },
{ alias: "datepicker", label: "Datepicker", view: "datepicker", config: { pickTime: false, format: "yyyy-MM-dd" } },
{ alias: "tags", label: "Tags", view: "tags", value: "" }
]
},
+77 -69
View File
@@ -1,69 +1,77 @@
app.config(function ($routeProvider) {
$routeProvider
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
if (rp.tree === "")
{
rp.tree = "default";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree/:method', {
templateUrl: function(rp) {
if (!rp.method){
return "views/common/dashboard.html";
}
if(rp.tree === "default" || rp.tree === ""){
return 'views/' + rp.section + '/' + rp.method + '.html';
}else{
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
}
})
.when('/:section/:tree/:method/:id', {
templateUrl: function (rp) {
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
})
.otherwise({ redirectTo: '/content/document' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
app.config(function ($routeProvider) {
$routeProvider
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
if (rp.tree === "")
{
rp.tree = "default";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree/:method', {
templateUrl: function(rp) {
if (!rp.method){
return "views/common/dashboard.html";
}
if(rp.tree === "default" || rp.tree === ""){
return 'views/' + rp.section + '/' + rp.method + '.html';
}else{
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
}
})
.when('/:section/:tree/:method/:id', {
templateUrl: function (rp) {
if (!rp.method)
return "views/common/dashboard.html";
////here we detect recycle bins, all recycle bins start with -2* (i.e. -20, -21)
//if (rp.id.startsWith("-2")) {
// return 'views/' + rp.section + '/recyclebin.html';
//}
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
})
.otherwise({ redirectTo: '/content/document' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,18 +0,0 @@
/* Show cursor when hovering dates and navigation arrows, to indicate they are clickable */
.datepicker-days .day,
.datepicker .add-on,
.datepicker-days .icon-arrow-right {
cursor: pointer;
}
.datepicker-days .day:hover {
background: #f8f8f7;
}
/* Ensures that the "select" color is not shown when clicking arrows in the datepicker window */
.datepicker-days .icon-arrow-right {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
File diff suppressed because it is too large Load Diff
@@ -1,27 +1,46 @@
angular.module("umbraco").controller("Umbraco.Editors.DatepickerController",
function ($scope, notificationsService, assetsService) {
assetsService.loadJs(
'views/propertyeditors/datepicker/bootstrap.datepicker.js'
).then(
function () {
//The Datepicker js and css files are available and all components are ready to use.
// Get the id of the datepicker button that was clicked
var pickerId = $scope.model.alias;
//setup the default config
var config = {
pickDate: true,
pickTime: true,
format: "yyyy-MM-dd HH:mm:ss"
};
//map the user config
angular.extend(config, $scope.model.config);
//map back to the model
$scope.model.config = config;
// Open the datepicker and add a changeDate eventlistener
$("#" + pickerId).datepicker({
format: "dd/mm/yyyy",
autoclose: true
}).on("changeDate", function (e) {
// When a date is clicked the date is stored in model.value as a ISO 8601 date
$scope.model.value = e.date.toIsoDateTimeString();
assetsService.loadJs(
'views/propertyeditors/datepicker/bootstrap-datetimepicker.min.js'
).then(
function () {
//The Datepicker js and css files are available and all components are ready to use.
// Get the id of the datepicker button that was clicked
var pickerId = $scope.model.alias;
// Open the datepicker and add a changeDate eventlistener
$("#" + pickerId).datetimepicker($scope.model.config).on("changeDate", function (e) {
// when a date is changed, update the model
if (e.localDate) {
if ($scope.model.config.format == "yyyy-MM-dd HH:mm:ss") {
$scope.model.value = e.localDate.toIsoDateTimeString();
}
else {
$scope.model.value = e.localDate.toIsoDateString();
}
}
else {
$scope.model.value = null;
}
});
});
});
assetsService.loadCss(
'views/propertyeditors/datepicker/bootstrap.datepicker.css'
);
});
assetsService.loadCss(
'views/propertyeditors/datepicker/bootstrap-datetimepicker.min.css'
);
});
@@ -1,6 +1,11 @@
<div ng-controller="Umbraco.Editors.DatepickerController">
<div class="input-append date datepicker" id="{{model.alias}}">
<input data-format="dd/MM/yyyy" type="text" value="{{model.value | date:'dd/MM/yyyy'}}" />
<span class="add-on"> <i class="icon-calendar"></i></span>
</div>
</div>
<div class="input-append date datepicker" id="{{model.alias}}">
<input name="datepicker" data-format="{{model.config.format}}" type="text"
ng-model="model.value"
val-server="value" />
<span class="add-on">
<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i>
</span>
</div>
<span class="help-inline" val-msg-for="datepicker" val-toggle-msg="valServer">{{propertyForm.datepicker.errorMsg}}</span>
</div>
@@ -7,8 +7,8 @@
var values = [];
//this will be comma delimited
if ($scope.value && (typeof $scope.value == "string")) {
var splitVals = $scope.value.split(",");
if ($scope.model.value && (typeof $scope.model.value == "string")) {
var splitVals = $scope.model.value.split(",");
//set the values of our object
for (var i = 0; i < splitVals.length; i++) {
values.push({
@@ -35,7 +35,7 @@
csv.push(newValue[v].value);
}
//write the csv value back to the property
$scope.value = csv.join();
$scope.model.value = csv.join();
}, true);
};
@@ -11,5 +11,5 @@
</ng-form>
</div>
<span>{{value}}</span>
<span>{{model.value}}</span>
</div>
@@ -1,8 +1,8 @@
<div ng-controller="MyPackage.PropertyEditors.PostcodeEditor">
<p>
Enter a postcode for country <span>{{config.country}}</span>
Enter a postcode for country <span>{{model.config.country}}</span>
</p>
<input name="myPackage_postcode" type="text" ng-model="value"
<input name="myPackage_postcode" type="text" ng-model="model.value"
val-server="value"
val-postcode="config.country"/>
@@ -1,10 +1,12 @@
<div ng-controller="MyPackage.PropertyEditors.RegexEditor">
<span>{{model.value}}</span>
<p>
Value in the format of <span>{{config}}</span>
Value in the format of <span>{{model.config}}</span>
</p>
<input name="regex" id="regex"
type="text" ng-model="value"
type="text" ng-model="model.value"
required
val-regex="config"
val-server="value" />
+2 -2
View File
@@ -114,9 +114,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -0,0 +1,76 @@
app.config(function ($routeProvider) {
$routeProvider
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
if (rp.tree === "")
{
rp.tree = "default";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree/:method', {
templateUrl: function(rp) {
if (!rp.method){
return "views/common/dashboard.html";
}
if(rp.tree === "default" || rp.tree === ""){
return 'views/' + rp.section + '/' + rp.method + '.html';
}else{
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
}
})
.when('/:section/:tree/:method/:id', {
templateUrl: function (rp) {
<<<<<<< HEAD
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
=======
if (!rp.method)
return "views/common/dashboard.html";
return 'views/' + rp.section + '/' + rp.method + '.html';
>>>>>>> 4a8026c902fd1f6afa32749882611c7e4d37e882
}
})
.otherwise({ redirectTo: '/content/document' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
@@ -0,0 +1,56 @@
app.config(function ($routeProvider) {
$routeProvider
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section/:method', {
templateUrl: function(rp) {
if (!rp.method)
return "views/common/dashboard.html";
return 'views/' + rp.section + '/' + rp.method + '.html';
}
})
.when('/:section/:method/:id', {
templateUrl: function (rp) {
if (!rp.method)
return "views/common/dashboard.html";
////here we detect recycle bins, all recycle bins start with -2* (i.e. -20, -21)
//if (rp.id.startsWith("-2")) {
// return 'views/' + rp.section + '/recyclebin.html';
//}
return 'views/' + rp.section + '/' + rp.method + '.html';
}
})
.otherwise({ redirectTo: '/content' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
@@ -0,0 +1,69 @@
app.config(function ($routeProvider) {
$routeProvider
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
if (rp.tree === "")
{
rp.tree = "default";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/:section/:tree/:method', {
templateUrl: function(rp) {
if (!rp.method){
return "views/common/dashboard.html";
}
if(rp.tree === "default" || rp.tree === ""){
return 'views/' + rp.section + '/' + rp.method + '.html';
}else{
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
}
})
.when('/:section/:tree/:method/:id', {
templateUrl: function (rp) {
return 'views/' + rp.section + '/' + rp.tree + '/' + rp.method + '.html';
}
})
.otherwise({ redirectTo: '/content/document' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
@@ -0,0 +1,51 @@
app.config(function ($routeProvider) {
$routeProvider
.when('/:section', {
templateUrl: function (rp) {
if (rp.section === "default")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/legacy.html';
}
})
.when('/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
}
})
.when('/:section/:method', {
templateUrl: function(rp) {
if (!rp.method)
return "views/common/dashboard.html";
return 'views/' + rp.section + '/' + rp.method + '.html';
}
})
.when('/:section/:method/:id', {
templateUrl: function (rp) {
if (!rp.method)
return "views/common/dashboard.html";
return 'views/' + rp.section + '/' + rp.method + '.html';
}
})
.otherwise({ redirectTo: '/content' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
app.run(['userService', function (userService) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
userService.isAuthenticated();
}]);
@@ -26,6 +26,5 @@ More information and documentation can be found on CodePlex: http://umbracoexami
<!-- Default Indexset for external searches, this indexes all fields on all types of nodes-->
<IndexSet SetName="ExternalIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/External/" />
</ExamineLuceneIndexSets>
@@ -21,7 +21,7 @@ More information and documentation can be found on CodePlex: http://umbracoexami
<!-- default external indexer, which excludes protected and published pages-->
<add name="ExternalIndexer" type="UmbracoExamine.UmbracoContentIndexer, UmbracoExamine"/>
</providers>
</ExamineIndexProviders>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="ClientDependency" version="1.7.0.4" targetFramework="net40" />
<package id="ClientDependency-Mvc" version="1.7.0.4" targetFramework="net40" />
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
+3 -1
View File
@@ -195,7 +195,9 @@ namespace Umbraco.Web.Editors
contentItem.PersistedContent.ExpireDate = contentItem.ExpireDate;
contentItem.PersistedContent.ReleaseDate = contentItem.ReleaseDate;
//only set the template if it didn't change
if (contentItem.PersistedContent.Template.Alias != contentItem.TemplateAlias)
var templateChanged = (contentItem.PersistedContent.Template == null && contentItem.TemplateAlias.IsNullOrWhiteSpace() == false)
|| (contentItem.PersistedContent.Template != null && contentItem.PersistedContent.Template.Alias != contentItem.TemplateAlias);
if (templateChanged)
{
var template = Services.FileService.GetTemplate(contentItem.TemplateAlias);
if (template == null)
@@ -1,5 +1,4 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Web.Http;
@@ -32,20 +31,4 @@ namespace Umbraco.Web.Models.ContentEditing
public string[] Urls { get; set; }
}
[DataContract(Name = "template", Namespace = "")]
public class TemplateBasic
{
[DataMember(Name = "id", IsRequired = true)]
[Required]
public int Id { get; set; }
[DataMember(Name = "name", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
[DataMember(Name = "alias", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string Alias { get; set; }
}
}
@@ -22,7 +22,7 @@ namespace Umbraco.Web.Models.ContentEditing
public string View { get; set; }
[DataMember(Name = "config")]
public IEnumerable<string> Config { get; set; }
public IDictionary<string, object> Config { get; set; }
[DataMember(Name = "hideLabel")]
public bool HideLabel { get; set; }
@@ -12,7 +12,6 @@ namespace Umbraco.Web.Models.ContentEditing
public IDataTypeDefinition DataType { get; set; }
public string Label { get; set; }
public string Description { get; set; }
public PropertyEditor PropertyEditor { get; set; }
public bool IsRequired { get; set; }
public string ValidationRegExp { get; set; }
}
@@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "template", Namespace = "")]
public class TemplateBasic
{
[DataMember(Name = "id", IsRequired = true)]
[Required]
public int Id { get; set; }
[DataMember(Name = "name", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string Name { get; set; }
[DataMember(Name = "alias", IsRequired = true)]
[Required(AllowEmptyStrings = false)]
public string Alias { get; set; }
}
}
@@ -14,6 +14,11 @@ namespace Umbraco.Web.Models.Mapping
internal class ContentPropertyBasicConverter<T> : TypeConverter<Property, T>
where T : ContentPropertyBasic, new()
{
/// <summary>
/// Assigns the PropertyEditor, Id, Alias and Value to the property
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
protected override T ConvertCore(Property property)
{
var editor = PropertyEditorResolver.Current.GetById(property.PropertyType.DataTypeId);
@@ -1,6 +1,8 @@
using Umbraco.Core;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Models.Mapping
@@ -25,7 +27,13 @@ namespace Umbraco.Web.Models.Mapping
display.Alias = originalProp.Alias;
display.Description = originalProp.PropertyType.Description;
display.Label = originalProp.PropertyType.Name;
display.Config = _applicationContext.Services.DataTypeService.GetPreValuesByDataTypeId(originalProp.PropertyType.DataTypeDefinitionId);
var dataTypeService = (DataTypeService) _applicationContext.Services.DataTypeService;
var preVals = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProp.PropertyType.DataTypeDefinitionId);
//let the property editor format the pre-values
display.Config = display.PropertyEditor.FormatPreValues(display.PropertyEditor.DefaultPreValues, preVals);
if (display.PropertyEditor == null)
{
//if there is no property editor it means that it is a legacy data type
@@ -23,11 +23,9 @@ namespace Umbraco.Web.Models.Mapping
propertyDto.IsRequired = originalProperty.PropertyType.Mandatory;
propertyDto.ValidationRegExp = originalProperty.PropertyType.ValidationRegExp;
propertyDto.Alias = originalProperty.Alias;
propertyDto.Description = originalProperty.PropertyType.Description;
propertyDto.Label = originalProperty.PropertyType.Name;
propertyDto.DataType = _applicationContext.Services.DataTypeService.GetDataTypeDefinitionById(originalProperty.PropertyType.DataTypeDefinitionId);
propertyDto.PropertyEditor = PropertyEditorResolver.Current.GetById(originalProperty.PropertyType.DataTypeId);
return propertyDto;
}
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[PropertyEditor(Constants.PropertyEditors.Date, "Date", "datepicker", ValueType = "DATE")]
public class DatePropertyEditor : PropertyEditor
{
public DatePropertyEditor()
{
_defaultPreVals = new Dictionary<string, object>
{
{"format", "yyyy-MM-dd"},
{"pickTime", false}
};
}
private IDictionary<string, object> _defaultPreVals;
/// <summary>
/// Overridden because we ONLY support Date (no time) format and we don't have pre-values in the db.
/// </summary>
public override IDictionary<string, object> DefaultPreValues
{
get { return _defaultPreVals; }
set { _defaultPreVals = value; }
}
protected override ValueEditor CreateValueEditor()
{
var baseEditor = base.CreateValueEditor();
return new DateValueEditor
{
View = baseEditor.View
};
}
/// <summary>
/// CUstom value editor so we can serialize with the correct date format (excluding time)
/// and includes the date validator
/// </summary>
private class DateValueEditor : ValueEditor
{
public DateValueEditor()
{
Validators = new List<ValidatorBase> { new DateTimeValidator() };
}
public override string SerializeValue(object dbValue)
{
var date = dbValue.TryConvertTo<DateTime?>();
if (date.Success == false || date.Result == null)
{
return string.Empty;
}
//Dates will be formatted as yyyy-MM-dd
return date.Result.Value.ToString("yyyy-MM-dd");
}
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
{
[PropertyEditor(Constants.PropertyEditors.DateTime, "Date/Time", "datepicker", ValueType = "DATETIME")]
public class DateTimePropertyEditor : PropertyEditor
{
public DateTimePropertyEditor()
{
_defaultPreVals = new Dictionary<string, object>
{
{"format", "yyyy-MM-dd HH:mm:ss"}
};
}
private IDictionary<string, object> _defaultPreVals;
/// <summary>
/// Overridden because we ONLY support Date + Time format and we don't have pre-values in the db.
/// </summary>
public override IDictionary<string, object> DefaultPreValues
{
get { return _defaultPreVals; }
set { _defaultPreVals = value; }
}
protected override ValueEditor CreateValueEditor()
{
var editor = base.CreateValueEditor();
editor.Validators = new List<ValidatorBase> { new DateTimeValidator() };
return editor;
}
}
}
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core;
namespace Umbraco.Web.PropertyEditors
{
/// <summary>
/// Used to validate if the value is a valid date/time
/// </summary>
internal class DateTimeValidator : ValidatorBase
{
public override IEnumerable<ValidationResult> Validate(string value, string preValues, PropertyEditor editor)
{
DateTime dt;
if (value.IsNullOrWhiteSpace() == false && DateTime.TryParse(value, out dt) == false)
{
yield return new ValidationResult(string.Format("The string value {0} cannot be parsed into a DateTime", value),
new[]
{
//we only store a single value for this editor so the 'member' or 'field'
// we'll associate this error with will simply be called 'value'
"value"
});
}
}
}
}
+6 -2
View File
@@ -106,9 +106,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.6.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -299,7 +299,11 @@
<Compile Include="Editors\AuthenticationController.cs" />
<Compile Include="Editors\ContentController.cs" />
<Compile Include="Editors\EntityController.cs" />
<Compile Include="Models\ContentEditing\TemplateBasic.cs" />
<Compile Include="Models\PagedResult.cs" />
<Compile Include="PropertyEditors\DatePropertyEditor.cs" />
<Compile Include="PropertyEditors\DateTimePropertyEditor.cs" />
<Compile Include="PropertyEditors\DateTimeValidator.cs" />
<Compile Include="PropertyEditors\LabelPropertyEditor.cs" />
<Compile Include="PropertyEditors\LabelValueEditor.cs" />
<Compile Include="Routing\UrlProviderExtensions.cs" />
+27 -18
View File
@@ -35,6 +35,7 @@ namespace Umbraco.Web
/// <param name="httpContext"></param>
static void BeginRequest(HttpContextBase httpContext)
{
//we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must
//exist on a global context because the keep alive service doesn't run in a web context.
//we are NOT going to put a lock on this because locking will slow down the application and we don't really care
@@ -170,26 +171,34 @@ namespace Umbraco.Web
var ticket = http.GetUmbracoAuthTicket();
if (ticket != null && !ticket.Expired && http.RenewUmbracoAuthTicket())
{
//create the Umbraco user identity
var identity = new UmbracoBackOfficeIdentity(ticket);
//set the principal object
var principal = new GenericPrincipal(identity, identity.Roles);
//It is actually not good enough to set this on the current app Context and the thread, it also needs
// to be set explicitly on the HttpContext.Current !! This is a strange web api thing that is actually
// an underlying fault of asp.net not propogating the User correctly.
if (HttpContext.Current != null)
try
{
HttpContext.Current.User = principal;
}
app.Context.User = principal;
Thread.CurrentPrincipal = principal;
//create the Umbraco user identity
var identity = new UmbracoBackOfficeIdentity(ticket);
//This is a back office request, we will also set the culture/ui culture
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(identity.Culture);
//set the principal object
var principal = new GenericPrincipal(identity, identity.Roles);
//It is actually not good enough to set this on the current app Context and the thread, it also needs
// to be set explicitly on the HttpContext.Current !! This is a strange web api thing that is actually
// an underlying fault of asp.net not propogating the User correctly.
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
app.Context.User = principal;
Thread.CurrentPrincipal = principal;
//This is a back office request, we will also set the culture/ui culture
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(identity.Culture);
}
catch (FormatException)
{
//this will occur if the cookie data is invalid
http.UmbracoLogout();
}
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
<package id="AutoMapper" version="2.2.1" targetFramework="net45" />
<package id="ClientDependency" version="1.7.0.4" targetFramework="net40" />
<package id="CodeSharp.Package.AspNetWebPage" version="1.0" targetFramework="net40" />
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
@@ -40,9 +40,9 @@
<Reference Include="AzureDirectory">
<HintPath>..\packages\AzureDirectory.1.0.5\lib\AzureDirectory.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="Examine.Azure, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AnglicanGeek.WindowsAzure.ServiceRuntime" version="1.6" targetFramework="net40" />
<package id="AzureDirectory" version="1.0.5" targetFramework="net40" />
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="Examine.Azure" version="0.1.51.2941" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
@@ -40,9 +40,9 @@
<Reference Include="AzureDirectory">
<HintPath>..\packages\AzureDirectory.1.0.5\lib\AzureDirectory.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="Examine.Azure, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AnglicanGeek.WindowsAzure.ServiceRuntime" version="1.6" targetFramework="net40" />
<package id="AzureDirectory" version="1.0.5" targetFramework="net40" />
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="Examine.Azure" version="0.1.51.2941" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
+63 -49
View File
@@ -12,6 +12,7 @@ using iTextSharp.text.pdf;
using System.Text;
using Lucene.Net.Analysis;
using UmbracoExamine.DataServices;
using iTextSharp.text.pdf.parser;
namespace UmbracoExamine.PDF
@@ -105,6 +106,7 @@ namespace UmbracoExamine.PDF
/// </summary>
/// <param name="name"></param>
/// <param name="config"></param>
[SecuritySafeCritical]
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
@@ -133,7 +135,7 @@ namespace UmbracoExamine.PDF
Action<Exception> onError = (e) => OnIndexingError(new IndexingErrorEventArgs("Could not read PDF", -1, e));
var txt = pdf.ParsePdfText(file.FullName, onError);
var txt = pdf.GetTextFromAllPages(file.FullName, onError);
return txt;
}
@@ -193,16 +195,21 @@ namespace UmbracoExamine.PDF
static PDFParser()
{
lock (m_Locker)
lock (Locker)
{
m_UnsupportedRange = new List<int>();
m_UnsupportedRange.AddRange(Enumerable.Range(0x0000, 0x001F));
m_UnsupportedRange.Add(0x1F);
UnsupportedRange = new HashSet<char>();
foreach (var c in Enumerable.Range(0x0000, 0x001F))
{
UnsupportedRange.Add((char) c);
}
UnsupportedRange.Add((char)0x1F);
//replace line breaks with space
ReplaceWithSpace = new HashSet<char> {'\r', '\n'};
}
}
private static readonly object m_Locker = new object();
private static readonly object Locker = new object();
/// <summary>
/// Stores the unsupported range of character
@@ -214,61 +221,68 @@ namespace UmbracoExamine.PDF
/// http://en.wikipedia.org/wiki/Unicode
/// http://en.wikipedia.org/wiki/Basic_Multilingual_Plane
/// </remarks>
private static List<int> m_UnsupportedRange;
private static HashSet<char> UnsupportedRange;
/// <summary>
/// Return only the valid string contents of the PDF
/// </summary>
/// <param name="sourcePDF"></param>
/// <param name="onError"></param>
/// <returns></returns>
[SecuritySafeCritical]
public string ParsePdfText(string sourcePDF, Action<Exception> onError)
private static HashSet<char> ReplaceWithSpace;
[SecuritySafeCritical]
public string GetTextFromAllPages(string pdfPath, Action<Exception> onError)
{
var sb = new StringBuilder();
var output = new StringWriter();
var reader = new PdfReader(sourcePDF);
PRTokeniser token = null;
var tknValue = String.Empty;
for (var i = 1; (i <= reader.NumberOfPages); i++)
try
{
var pageBytes = reader.GetPageContent(i);
if (pageBytes != null)
{
token = new PRTokeniser(pageBytes);
try
{
while (token.NextToken())
{
var tknType = token.TokenType;
tknValue = token.StringValue;
if ((tknType == PRTokeniser.TokType.STRING))
{
foreach (var s in tknValue)
{
//strip out unsupported characters, based on unicode tables.
if (!m_UnsupportedRange.Contains(s))
{
sb.Append(s);
}
}
var reader = new PdfReader(pdfPath);
}
}
}
catch (InvalidPdfException ex)
{
onError(ex);
}
for (int i = 1; i <= reader.NumberOfPages; i++)
{
var result =
ExceptChars(
PdfTextExtractor.GetTextFromPage(reader, i, new SimpleTextExtractionStrategy()),
UnsupportedRange,
ReplaceWithSpace);
output.Write(result);
}
}
catch (Exception ex)
{
onError(ex);
}
return sb.ToString();
return output.ToString();
}
}
/// <summary>
/// remove all toExclude chars from string
/// </summary>
/// <param name="str"></param>
/// <param name="toExclude"></param>
/// <param name="replaceWithSpace"></param>
/// <returns></returns>
private static string ExceptChars(string str, HashSet<char> toExclude, HashSet<char> replaceWithSpace)
{
var sb = new StringBuilder(str.Length);
for (var i = 0; i < str.Length; i++)
{
var c = str[i];
if (toExclude.Contains(c) == false)
{
if (replaceWithSpace.Contains(c))
{
sb.Append(" ");
}
else
{
sb.Append(c);
}
}
}
return sb.ToString();
}
#endregion
}
@@ -28,4 +28,5 @@ using System.Security;
[assembly: AssemblyVersion("0.6.0.*")]
[assembly: AssemblyFileVersion("0.6.0.*")]
[assembly: AllowPartiallyTrustedCallers]
//Unfortunately itextsharp does not natively support full trust
//[assembly: AllowPartiallyTrustedCallers]
@@ -46,9 +46,9 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="iTextSharp" version="5.3.3" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
+1
View File
@@ -96,6 +96,7 @@ namespace UmbracoExamine
/// </summary>
/// <param name="name"></param>
/// <param name="config"></param>
[SecuritySafeCritical]
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (config["dataService"] != null && !string.IsNullOrEmpty(config["dataService"]))
@@ -124,6 +124,7 @@ namespace UmbracoExamine
/// <exception cref="T:System.InvalidOperationException">
/// An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/> on a provider after the provider has already been initialized.
/// </exception>
[SecuritySafeCritical]
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
+2 -2
View File
@@ -82,9 +82,9 @@
<AssemblyOriginatorKeyFile>..\Solution Items\TheFARM-Public.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -45,6 +45,7 @@ namespace UmbracoExamine
}
}
[SecuritySafeCritical]
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (name == null) throw new ArgumentNullException("name");
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
</packages>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Examine" version="0.1.51.2941" targetFramework="net40" />
<package id="Examine" version="0.1.52.2941" targetFramework="net40" />
<package id="HtmlAgilityPack" version="1.4.6" targetFramework="net40" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" />
@@ -45,9 +45,9 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Examine, Version=0.1.51.2941, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="Examine, Version=0.1.52.2941, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Examine.0.1.51.2941\lib\Examine.dll</HintPath>
<HintPath>..\packages\Examine.0.1.52.2941\lib\Examine.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.6.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
+27 -18
View File
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
@@ -308,27 +309,35 @@ namespace umbraco
{
var cacheKey = "uitext_" + language;
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
cacheKey,
CacheItemPriority.Default,
new CacheDependency(IOHelper.MapPath(UmbracoPath + "/config/lang/" + language + ".xml")),
() =>
{
using (var langReader = new XmlTextReader(IOHelper.MapPath(UmbracoPath + "/config/lang/" + language + ".xml")))
var file = IOHelper.MapPath(UmbracoPath + "/config/lang/" + language + ".xml");
if (File.Exists(file))
{
return ApplicationContext.Current.ApplicationCache.GetCacheItem(
cacheKey,
CacheItemPriority.Default,
new CacheDependency(IOHelper.MapPath(UmbracoPath + "/config/lang/" + language + ".xml")),
() =>
{
try
using (var langReader = new XmlTextReader(IOHelper.MapPath(UmbracoPath + "/config/lang/" + language + ".xml")))
{
var langFile = new XmlDocument();
langFile.Load(langReader);
return langFile;
try
{
var langFile = new XmlDocument();
langFile.Load(langReader);
return langFile;
}
catch (Exception e)
{
LogHelper.Error<ui>("Error reading umbraco language xml source (" + language + ")", e);
return null;
}
}
catch (Exception e)
{
LogHelper.Error<ui>("Error reading umbraco language xml source (" + language + ")", e);
return null;
}
}
});
});
}
else
{
return null;
}
}
@@ -106,7 +106,7 @@ namespace umbraco.editorControls
public void Save()
{
if (ItemIdValue.Value.Trim() != "")
_data.Value = ItemIdValue.Value.Trim();
_data.Value = int.Parse(ItemIdValue.Value.Trim());
else
_data.Value = null;
}
@@ -10,6 +10,7 @@ using System.Xml.Linq;
using ClientDependency.Core;
using Umbraco.Core;
using Umbraco.Core.IO;
using umbraco.BusinessLogic;
using umbraco.cms.presentation.Trees;
using umbraco.controls.Images;
using umbraco.controls.Tree;
@@ -45,7 +46,15 @@ namespace umbraco.editorControls.MultiNodeTreePicker
//need to add our tree definitions to the collection.
//find the content tree to duplicate
var contentTree = TreeDefinitionCollection.Instance.Single(x => string.Equals(x.Tree.Alias, Umbraco.Core.Constants.Applications.Content, StringComparison.OrdinalIgnoreCase));
var contentTree = TreeDefinitionCollection.Instance.SingleOrDefault(x => string.Equals(x.Tree.Alias, Umbraco.Core.Constants.Applications.Content, StringComparison.OrdinalIgnoreCase));
//have put this here because the legacy content tree no longer exists as a tree def
if (contentTree == null)
{
contentTree = new TreeDefinition(
typeof (loadContent),
new ApplicationTree(false, true, 0, "content", "content", "Content", ".sprTreeFolder", ".sprTreeFolder_o", "", typeof (loadContent).GetFullNameWithAssembly(), ""),
new Application("Content", "content", "content"));
}
var filteredContentTree = new TreeDefinition(typeof(FilteredContentTree),
new umbraco.BusinessLogic.ApplicationTree(true, false, 0,
contentTree.Tree.ApplicationAlias,
@@ -59,7 +68,15 @@ namespace umbraco.editorControls.MultiNodeTreePicker
contentTree.App);
//find the media tree to duplicate
var mediaTree = TreeDefinitionCollection.Instance.Single(x => string.Equals(x.Tree.Alias, Umbraco.Core.Constants.Applications.Media, StringComparison.OrdinalIgnoreCase));
var mediaTree = TreeDefinitionCollection.Instance.SingleOrDefault(x => string.Equals(x.Tree.Alias, Umbraco.Core.Constants.Applications.Media, StringComparison.OrdinalIgnoreCase));
//have put this here because the legacy content tree no longer exists as a tree def
if (mediaTree == null)
{
mediaTree = new TreeDefinition(
typeof(loadMedia),
new ApplicationTree(false, true, 0, "media", "media", "Media", ".sprTreeFolder", ".sprTreeFolder_o", "", typeof(loadMedia).GetFullNameWithAssembly(), ""),
new Application("Media", "media", "media"));
}
var filteredMediaTree = new TreeDefinition(typeof(FilteredMediaTree),
new umbraco.BusinessLogic.ApplicationTree(true, false, 0,
mediaTree.Tree.ApplicationAlias,