diff --git a/AzurePackage.proj b/AzurePackage.proj index 696168b1e..5ae8072d0 100644 --- a/AzurePackage.proj +++ b/AzurePackage.proj @@ -48,7 +48,8 @@ + Properties="Configuration=Release;OutputPath=$(CompileFolder);PlatformTarget=x64;DefineConstants=AZURE" + /> YamlSerializer - + - Converts various types to / from string.
- I don't remember why this class was needed.... + Type 関連のユーティリティメソッド
- object obj = GetObjectToConvert(); + Type type; + AttributeType attr = type.GetAttribute<AttributeType>(); - // Check if the type has [TypeConverter] attribute. - if( EasyTypeConverter.IsTypeConverterSpecified(type) ) { + PropertyInfo propInfo; + AttributeType attr = propInfo.GetAttribute<AttributeType>(); - // Convert the object to string. - string s = EasyTypeConverter.ConvertToString(obj); + string name; + Type type = TypeUtils.GetType(name); // search from all assembly loaded - // Convert the string to an object of the spific type. - object restored = EasyTypeConverter.ConvertFromString(s, type); - - Assert.AreEqual(obj, restored); - }
+ + + Type や PropertyInfo, FieldInfo から指定された型の属性を取り出して返す + 複数存在した場合には最後の値を返す + 存在しなければ null を返す + + 取り出したい属性の型 + 取り出した属性値 + + + + 現在ロードされているすべてのアセンブリから name という名の型を探して返す + + + + + + + Check if the type is a ValueType and does not contain any non ValueType members. + + + + + + + Returnes true if the specified is a struct type. + + to be analyzed. + true if the specified is a struct type; otehrwise false. + + + + Compare two objects to see if they are equal or not. Null is acceptable. + + + + + + + + Return if an object is a numeric value. + + Any object to be tested. + True if object is a numeric value. + + + + Cast an object to a specified numeric type. + + Any object + Numric type + Numeric value or null if the object is not a numeric value. + + + + Cast boxed numeric value to double + + boxed numeric value + Numeric value in double. Double.Nan if obj is not a numeric value. + + + + Check if type is fully public or not. + Nested class is checked if all declared types are public. + + + + + + + Equality comparer that uses Object.ReferenceEquals(x, y) to compare class values. + + + + + + Determines whether two objects of type T are equal by calling Object.ReferenceEquals(x, y). + + The first object to compare. + The second object to compare. + true if the specified objects are equal; otherwise, false. + + + + Serves as a hash function for the specified object for hashing algorithms and + data structures, such as a hash table. + + The object for which to get a hash code. + A hash code for the specified object. + is null. + + + + Returns a default equality comparer for the type specified by the generic argument. + + The default instance of the System.Collections.Generic.EqualityComparer<T> + class for type T. + + + + + object に代入されたクラスや構造体のメンバーに、リフレクションを + 解して簡単にアクセスできるようにしたクラス + + アクセス方法をキャッシュするので、繰り返し使用する場合に高速化が + 期待できる + + + + + Caches ObjectMemberAccessor instances for reuse. + + + + + + 指定した型へのアクセス方法を表すインスタンスを返す + キャッシュに存在すればそれを返す + キャッシュに存在しなければ新しく作って返す + 作った物はキャッシュされる + + クラスまたは構造体を表す型情報 + + + + + メンバ名と Accessor のペアを巡回する + + + + + + メンバへの読み書きを行うことができる + + オブジェクト + メンバの名前 + + + + + class has instance methods and , + with which C# native objects can be converted into / from YAML text without any preparations. + + var serializer = new YamlSerializer(); + object obj = GetObjectToSerialize(); + string yaml = serializer.Serialize(obj); + object restored = serializer.Deserialize(yaml); + Assert.AreEqual(obj, restored); + + + + +

What kind of objects can be serialized?

+ + can serialize / deserialize native C# objects of primitive types + (bool, char, int,...), enums, built-in non-primitive types (string, decimal), structures, + classes and arrays of these types. + + + On the other hand, it does not deal with IntPtr (which is a primitive type, though) and + pointer types (void*, int*, ...) because these types are, by their nature, not persistent. + + + + Classes without a default constructor can be deserialized only when the way of activating an instance + is explicitly specified by . + + + + object obj = new object[]{ + null, + "abc", + true, + 1, + (Byte)1, + 1.0, + "1", + new double[]{ 1.1, 2, -3 }, + new string[]{ "def", "ghi", "1" }, + new System.Drawing.Point(1,3), + new System.Drawing.SolidBrush(Color.Blue) + }; + + var serializer = new YamlSerializer(); + string yaml = serializer.Serialize(obj); + // %YAML 1.2 + // --- + // - null + // - abc + // - True + // - 1 + // - !System.Byte 1 + // - !!float 1 + // - "1" + // - !<!System.Double[]%gt; [1.1, 2, -3] + // - !<!System.String[]%gt; + // - def + // - ghi + // - !System.Drawing.Point 1, 3 + // - !System.Drawing.SolidBrush + // Color: Blue + // ... + + object restored; + try { + restored = YamlSerializer.Deserialize(yaml)[0]; + } catch(MissingMethodException) { + // default constructor is missing for SolidBrush + } + + // Let the library know how to activate an instance of SolidBrush. + YamlNode.DefaultConfig.AddActivator<System.Drawing.SolidBrush>( + () => new System.Drawing.SolidBrush(Color.Black /* dummy */)); + + // Then, all the objects can be restored correctly. + restored = serializer.Deserialize(yaml)[0]; + + + A YAML document generated by always have a %YAML directive and + explicit document start ("---") and end ("...") marks. + This allows several documents to be written in a single YAML stream. + + + var yaml = ""; + var serializer = new YamlSerializer(); + yaml += serializer.Serialize("a"); + yaml += serializer.Serialize(1); + yaml += serializer.Serialize(1.1); + // %YAML 1.2 + // --- + // a + // ... + // %YAML 1.2 + // --- + // 1 + // ... + // %YAML 1.2 + // --- + // 1.1 + // ... + + object[] objects = serializer.Deserialize(yaml); + // objects[0] == "a" + // objects[1] == 1 + // objects[2] == 1.1 + + + Since a YAML stream can consist of multiple YAML documents as above, + returns an array of . + + +

Serializing structures and classes

+ + For structures and classes, by default, all public fields and public properties are + serialized. Note that protected / private members are always ignored. + +

Serialization methods

+ + Readonly value-type members are also ignored because there is no way to + assign a new value to them on deserialization, while readonly class-type members + are serialized. When deserializing, instead of creating a new object and assigning it + to the member, the child members of such class instance are restored independently. + Such a deserializing method is refered to + YamlSerializeMethod.Content. + + + On the other hand, when writeable fields/properties are deserialized, new objects are + created by using the parameters in the YAML description and assiend to the fields/properties. + Such a deserializing method is refered to + YamlSerializeMethod.Assign. Writeable properties can be explicitly specified to use + YamlSerializeMethod.Content method for + deserialization, by adding to its definition. + + + Another type of serializing method is + YamlSerializeMethod.Binary. + This method is only applicable to an array-type field / property that contains + only value-type members. + + If serializing method is specified, + the member is never serialized nor deserialized. + + + public class Test1 + { + public int PublicProp { get; set; } // processed (by assign) + protected int ProtectedProp { get; set; } // Ignored + private int PrivateProp { get; set; } // Ignored + internal int InternalProp { get; set; } // Ignored + + public int PublicField; // processed (by assign) + protected int ProtectedField; // Ignored + private int PrivateField; // Ignored + internal int InternalField; // Ignored + + public List<string> ClassPropByAssign // processed (by assign) + { get; set; } + + public int ReadOnlyValueProp { get; private set; } // Ignored + public List<string> ReadOnlyClassProp // processed (by content) + { get; private set; } + + [YamlSerialize(YamlSerializeMethod.Content)] + public List<string> ClassPropByContent// processed (by content) + { get; set; } + + public int[] IntArrayField = // processed (by assign) + new int[10]; + + [YamlSerialize(YamlSerializeMethod.Binary)] + public int[] IntArrayFieldBinary = // processed (as binary) + new int[100]; + + [YamlSerialize(YamlSerializeMethod.Never)] + public int PublicPropHidden; // Ignored + + public Test1() + { + ClassPropByAssign = new List<string>(); + ReadOnlyClassProp = new List<string>(); + ClassPropByContent = new List<string>(); + } + } + + public void TestPropertiesAndFields1() + { + var test1 = new Test1(); + test1.ClassPropByAssign.Add("abc"); + test1.ReadOnlyClassProp.Add("def"); + test1.ClassPropByContent.Add("ghi"); + var rand = new Random(0); + for ( int i = 0; i < test1.IntArrayFieldBinary.Length; i++ ) + test1.IntArrayFieldBinary[i] = rand.Next(); + + var serializer = new YamlSerializer(); + string yaml = serializer.Serialize(test1); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test1 + // PublicProp: 0 + // ClassPropByAssign: + // Capacity: 4 + // ICollection.Items: + // - abc + // ReadOnlyClassProp: + // Capacity: 4 + // ICollection.Items: + // - def + // ClassPropByContent: + // Capacity: 4 + // ICollection.Items: + // - ghi + // PublicField: 0 + // IntArrayField: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + // IntArrayFieldBinary: |+2 + // Gor1XAwenmhGkU5ib9NxR11LXxp1iYlH5LH4c9hImTitWSB9Z78II2UvXSXV99A79fj6UBn3GDzbIbd9 + // yBDjAyslYm58iGd/NN+tVjuLRCg3cJBo+PWMbIWm9n4AEC0E7LKXWV5HXUNk7I13APEDWFMM/kWTz2EK + // s7LzFw2gBjpKugkmQJqIfinpQ1J1yqhhz/XjA3TBxDBsEuwrD+SNevQSqEC+/KRbwgE6D011ACMeyRt0 + // BOG6ZesRKCtL0YU6tSnLEpgKVBz+R300qD3/W0aZVk+1vHU+auzyGCGUaHCGd6dpRoEhXoIg2m3+AwJX + // EJ37T+TA9BuEPJtyGoq+crQMFQtXj1Zriz3HFbReclLvDdVpZlcOHPga/3+3Y509EHZ7UyT7H1xGeJxn + // eXPrDDb0Ul04MfZb4UYREOfR3HNzNTUYGRsIPUvHOEW7AaoplIfkVQp19DvGBrBqlP2TZ9atlWUHVdth + // 7lIBeIh0wiXxoOpCbQ7qVP9GkioQUrMkOcAJaad3exyZaOsXxznFCA== + // ... + } + + +

Default values of fields and properties

+ + is aware of + System.ComponentModel.DefaultValueAttribute. + So, when a member of a structure / class instance has a value that equals to the default value, + the member will not be written in the YAML text. + + It also checkes for the result of ShouldSerializeXXX method. For instance, just before serializing Font + property of some type, bool ShouldSerializeFont() method is called if exists. If the method returns false, + Font property will not be written in the YAML text. ShouldSerializeXXX method can be non-public. + + + using System.ComponentModel; + + public class Test2 + { + [DefaultValue(0)] + public int Default0 = 0; + + [DefaultValue("a")] + public string Defaulta = "a"; + + public int DynamicDefault = 0; + + bool ShouldSerializeDynamicDefault() + { + return Default0 != DynamicDefault; + } + } + + public void TestDefaultValue() + { + var test2 = new Test2(); + var serializer = new YamlSerializer(); + + // All properties have defalut values. + var yaml = serializer.Serialize(test2); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test2 {} + // ... + + test2.Defaulta = "b"; + yaml = serializer.Serialize(test2); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test2 + // Defaulta: b + // ... + + test2.Defaulta = "a"; + var yaml = serializer.Serialize(test2); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test2 {} + // ... + + test2.DynamicDefault = 1; + yaml = serializer.Serialize(test2); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test2 + // DynamicDefault: 1 + // ... + + test2.Default0 = 1; + yaml = serializer.Serialize(test2); + // %YAML 1.2 + // --- + // !YamlSerializerTest.Test2 + // Default0: 1 + // ... + } + + +

Collection classes

+ + If an object implements , or + the child objects are serialized as well its other public members. + Pseudproperty ICollection.Items or IDictionary.Entries appears to hold the child objects. + +

Multitime appearance of a same object

+ + preserve C# objects' graph structure. Namely, when a same objects are refered to + from several points in the object graph, the structure is correctly described in YAML text and restored objects + preserve the structure. can safely manipulate directly / indirectly self refering + objects, too. + + + public class TestClass + { + public List<TestClass> list = + new List<TestClass>(); + } + + public class ChildClass: TestClass + { + } + + void RecursiveObjectsTest() + { + var a = new TestClass(); + var b = new ChildClass(); + a.list.Add(a); + a.list.Add(a); + a.list.Add(b); + a.list.Add(a); + a.list.Add(b); + b.list.Add(a); + var serializer = new YamlSerializer(); + string yaml = serializer.Serialize(a); + // %YAML 1.2 + // --- + // &A !TestClass + // list: + // Capacity: 8 + // ICollection.Items: + // - *A + // - *A + // - &B !ChildClass + // list: + // Capacity: 4 + // ICollection.Items: + // - *A + // - *A + // - *B + // ... + + var restored = (TestClass)serializer.Deserialize(yaml)[0]; + Assert.IsTrue(restored == restored.list[0]); + Assert.IsTrue(restored == restored.list[1]); + Assert.IsTrue(restored == restored.list[3]); + Assert.IsTrue(restored == restored.list[5]); + Assert.IsTrue(restored.list[2] == restored.list[4]); + } + + + This is not the case if the object is . Same instances of + are repeatedly written in a YAML text and restored as different + instance of when deserialized, unless the content of the string + is extremely long (longer than 999 chars). + + + // 1000 chars + string long_str = + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; + string short_str = "12345"; + object obj = new object[] { long_str, long_str, short_str, short_str }; + var serializer = new YamlSerializer(); + string yaml = serializer.Serialize(obj); + // %YAML 1.2 + // --- + // - &A 01234567890123456789012345678901234567890123456789 ... (snip) ... 789 + // - *A + // - "12345" + // - "12345" + // ... + + +

YAML text written / read by

+ + When serializing, intelligently uses various YAML 1.2 styles, + namely the block style, flow style, explicit mapping and implicit mapping, to maximize readability + of the YAML stream. + + + [Flags] + enum TestEnum: uint + { + abc = 1, + あいう = 2 + } + + public void TestVariousFormats() + { + var dict = new Dictionary<object, object>(); + dict.Add(new object[] { 1, "a" }, new object()); + object obj = new object[]{ + dict, + null, + "abc", + "1", + "a ", + "- a", + "abc\n", + "abc\ndef\n", + "abc\ndef\nghi", + new double[]{ 1.1, 2, -3, 3.12, 13.2 }, + new int[,] { { 1, 3}, {4, 5}, {10, 1} }, + new string[]{ "jkl", "mno\npqr" }, + new System.Drawing.Point(1,3), + TestEnum.abc, + TestEnum.abc | TestEnum.あいう, + }; + var config = new YamlConfig(); + config.ExplicitlyPreserveLineBreaks = false; + var serializer = new YamlSerializer(config); + string yaml = serializer.Serialize(obj); + + // %YAML 1.2 + // --- + // - !<!System.Collections.Generic.Dictionary%602[[System.Object,...],[System.Object,...]]> + // Keys: {} + // Values: {} + // IDictionary.Entries: + // ? - 1 + // - a + // : !System.Object {} + // - null + // - abc + // - "1" + // - "a " + // - "- a" + // - "abc\n" + // - |+2 + // abc + // def + // - |-2 + // abc + // def + // ghi + // - !<!System.Double[]> [1.1, 2, -3, 3.12, 13.2] + // - !<!System.Int32[,]> [[1, 3], [4, 5], [10, 1]] + // - !<!System.String[]> + // - jkl + // - |-2 + // mno + // pqr + // - !System.Drawing.Point 1, 3 + // - !TestEnum abc + // - !TestEnum abc, あいう + // ... + } + + + When deserializing, accepts any valid YAML 1.2 documents. + TAG directives, comments, flow / block styles, implicit / explicit mappings can be freely used + to express valid C# objects. Namely, the members of the array can be given eighter in a flow style + or in a block style. + + + By default, outputs a YAML stream with line break of "\r\n". + This can be customized either by setting YamlNode.DefaultConfig.LineBreakForOutput or + by giving an instance of to the + constructor. + + + + var serializer = new YamlSerializer(); + var yaml = serializer.Serialize("abc"); + // %YAML 1.2\r\n // line breaks are explicitly shown in this example + // ---\r\n + // abc\r\n + // ...\r\n + + var config = new YamlConfig(); + config.LineBreakForOutput = "\n"; + serializer = new YamlSerializer(config); + var yaml = serializer.Serialize("abc"); + // %YAML 1.2\n + // ---\n + // abc\n + // ...\n + + YamlNode.DefaultConfig.LineBreakForOutput = "\n"; + + var serializer = new YamlSerializer(); + serializer = new YamlSerializer(); + var yaml = serializer.Serialize("abc"); + // %YAML 1.2\n + // ---\n + // abc\n + // ...\n + + +

Line breaks in YAML text

+ + By default, line breaks in multi line values are explicitly presented as escaped style. + Although, this makes the resulting YAML stream hard to read, it is necessary to preserve + the exact content of the string because the YAML specification requires that a YAML parser + must normalize evely line break that is not escaped in a YAML document to be a single line + feed "\n" when deserializing. + + In order to have the YAML documents easy to be read, set + YamlConfig.ExplicitlyPreserveLineBreaks + false. Then, the multiline values of will be written in literal style. + + Of course, it makes all the line breaks to be normalized into a single line feeds "\n". + + + var serializer = new YamlSerializer(); + var text = "abc\r\n def\r\nghi\r\n"; + // abc + // def + // ghi + + // By default, line breaks explicitly appears in escaped form. + var yaml = serializer.Serialize(text); + // %YAML 1.2 + // --- + // "abc\r\n\ + // \ def\r\n\ + // ghi\r\n" + // ... + + // Original line breaks are preserved + var restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\r\n def\r\nghi\r\n" + + + YamlNode.DefaultConfig.ExplicitlyPreserveLineBreaks = false; + + // Literal style is easier to be read. + var yaml = serializer.Serialize(text); + // %YAML 1.2 + // --- + // |+2 + // abc + // def + // ghi + // ... + + // Original line breaks are lost. + var restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\n def\nghi\n" + + + This library offers two work arounds for this problem, although both of which + violates the official behavior of a YAML parser defined in the YAML specification. + + One is to set YamlConfig.LineBreakForInput + to be "\r\n". Then, the YAML parser normalizes all line breaks into "\r\n" instead of "\n". + + The other is to set YamlConfig.NormalizeLineBreaks + false. It disables the line break normalization both at output and at input. Namely, the line breaks are + written and read as-is when serialized / deserialized. + + + var serializer = new YamlSerializer(); + + // text with mixed line breaks + var text = "abc\r def\nghi\r\n"; + // abc\r // line breaks are explicitly shown in this example + // def\n + // ghi\r\n + + YamlNode.DefaultConfig.ExplicitlyPreserveLineBreaks = false; + + // By default, all line breaks are normalized to "\r\n" when serialized. + var yaml = serializer.Serialize(text); + // %YAML 1.2\r\n + // ---\r\n + // |+2\r\n + // abc\r\n + // def\r\n + // ghi\r\n + // ...\r\n + + // When deserialized, line breaks are normalized into "\n". + var restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\n def\nghi\n" + + // Line breaks are normalized into "\r\n" instead of "\n". + YamlNode.DefaultConfig.LineBreakForInput = "\r\n"; + restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\r\n def\r\nghi\r\n" + + // Line breaks are written as is, + YamlNode.DefaultConfig.NormalizeLineBreaks = false; + var yaml = serializer.Serialize(text); + // %YAML 1.2\r\n + // ---\r\n + // |+2\r\n + // abc\r + // def\n + // ghi\r\n + // ...\r\n + + // and are read as is. + restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\r def\nghi\r\n" + + // Note that when the line breaks of YAML stream is changed + // between serialization and deserialization, the original + // line breaks are lost. + yaml = yaml.Replace("\r\n", "\n").Replace("\r", "\n"); + restored = (string)serializer.Deserialize(yaml)[0]; + // "abc\n def\nghi\n" + + + It is repeatedly stated that although these two options are useful in many situation, + they makes the YAML parser violate the YAML specification. + +
+
+ + + Initialize an instance of that obeys + . + + + + + Initialize an instance of with custom . + + Custom to customize serialization. + + + + Serialize C# object into YAML text. + + Object to be serialized. + YAML text. + + + + Serialize C# object into YAML text and write it into a . + + A to which the YAML text is written. + Object to be serialized. + + + + Serialize C# object into YAML text and write it into a . + + A to which the YAML text is written. + Object to be serialized. + + + + Serialize C# object into YAML text and save it into a file named as . + + A file name to which the YAML text is written. + Object to be serialized. + + + + Deserialize C# object(s) from a YAML text. Since a YAML text can contain multiple YAML documents, each of which + represents a C# object, the result is returned as an array of . + + A YAML text from which C# objects are deserialized. + Expected type(s) of the root object(s) in the YAML stream. + C# object(s) deserialized from YAML text. + + + + Deserialize C# object(s) from a YAML text in a . + Since a YAML text can contain multiple YAML documents, each of which + represents a C# object, the result is returned as an array of . + + A that contains YAML text from which C# objects are deserialized. + Expected type(s) of the root object(s) in the YAML stream. + C# object(s) deserialized from YAML text. + + + + Deserialize C# object(s) from a YAML text in a . + Since a YAML text can contain multiple YAML documents, each of which + represents a C# object, the result is returned as an array of . + + A that contains YAML text from which C# objects are deserialized. + Expected type(s) of the root object(s) in the YAML stream. + C# object(s) deserialized from YAML text. + + + + Deserialize C# object(s) from a YAML text in a file named as . + Since a YAML text can contain multiple YAML documents, each of which + represents a C# object, the result is returned as an array of . + + The name of a file that contains YAML text from which C# objects are deserialized. + Expected type(s) of the root object(s) in the YAML stream. + C# object(s) deserialized from YAML text. + + + + Add .DoFunction method to string + + + + + Short expression of string.Format(XXX, arg1, arg2, ...) + + + + + + + + Specify the way to store a property or field of some class or structure. + See for detail. + + + + + + + The property / field will not be stored. + + + + + When restored, new object is created by using the parameters in + the YAML data and assigned to the property / field. When the + property / filed is writeable, this is the default. + + + + + Only valid for a property / field that has a class or struct type. + When restored, instead of recreating the whole class or struct, + the members are independently restored. When the property / field + is not writeable this is the default. + + + + + Only valid for a property / field that has an array type of a + some value type. The content of the array is stored in a binary + format encoded in base64 style. + + + + + Specify the way to store a property or field of some class or structure. + + See for detail. + + + + + + + Specify the way to store a property or field of some class or structure. + + See for detail. + + + + + + - Never: The property / field will not be stored. + + + - Assign: When restored, new object is created by using the parameters in + the YAML data and assigned to the property / field. When the + property / filed is writeable, this is the default. + + + - Content: Only valid for a property / field that has a class or struct type. + When restored, instead of recreating the whole class or struct, + the members are independently restored. When the property / field + is not writeable this is the default. + + + - Binary: Only valid for a property / field that has an array type of a + some value type. The content of the array is stored in a binary + format encoded in base64 style. + + + Converts C# object to YamlNode @@ -855,6 +1786,52 @@ Column in a text. + + + Converts various types to / from string.
+ I don't remember why this class was needed.... +
+ + + object obj = GetObjectToConvert(); + + // Check if the type has [TypeConverter] attribute. + if( EasyTypeConverter.IsTypeConverterSpecified(type) ) { + + // Convert the object to string. + string s = EasyTypeConverter.ConvertToString(obj); + + // Convert the string to an object of the spific type. + object restored = EasyTypeConverter.ConvertFromString(s, type); + + Assert.AreEqual(obj, restored); + + } + + +
+ + + Construct YAML node tree that represents a given C# object. + + + + + Construct YAML node tree that represents a given C# object. + + to be converted to C# object. + to customize serialization. + + + + + Construct YAML node tree that represents a given C# object. + + to be converted to C# object. + Expected type for the root object. + to customize serialization. + + Validates a text as a global tag in YAML. @@ -874,74 +1851,6 @@ Not used in this parser - - - Dictionary that automatically rehash when the content of a key is changed. - Keys of this dictionary must implement . - It also call back item addition and removal by and - events. - - Type of key. Must implements . - Type of value. - - - - A dictionary that returns or - from hash code. This is the main repository that stores the pairs. - If there are several entries that have same hash code for thir keys, - a is stored to hold all those entries. - Otherwise, a is stored. - - - - - A dictionary that returns hash code from the key reference. - The key must be the instance that - to one exsisting in the dictionary. - - - We store the hashes correspoinding to each key. So that when rehash, - we can find old hash code to quickly find the entry for the key. - It is also used to remember the number of keys exists in the dictionary. - - - - - Recalc hash key of the . - - The key to be rehash. The key must be the instance that - to one exsisting in the dictionary. - - - - Try to find entry for key (and value). - - key to find - if true, value matters - value to find - key not found - hash hit one entry and key found - hash hit several entries and key found - - - - Try to find entry for key (and value). - - key to find - if true, value matters - value to find - hash not found - hash hit one entry but key not found - hash hit one entry and key found - hash hit several entries but key not found - hash hit several entries and key found - - - - Collection that is readonly and invalidated when an item is - added to or removed from the dictionary. - - A text parser for
@@ -1095,67 +2004,6 @@ [23]
- - - Construct YAML node tree that represents a given C# object. - - - - - Construct YAML node tree that represents a given C# object. - - to be converted to C# object. - to customize serialization. - - - - - Construct YAML node tree that represents a given C# object. - - to be converted to C# object. - Expected type for the root object. - to customize serialization. - - - - - Add string class two methods: .UriEscape(), .UriUnescape() - - Charset that is not escaped is represented NonUriChar member. - - NonUriChar = new Regex(@"[^0-9A-Za-z\-_.!~*'()\\;/?:@&=$,\[\]]"); - - - - - Escape the string in URI encoding format. - - String to be escaped. - Escaped string. - - - - Escape the string in URI encoding format. - - String to be escaped. - Escaped string. - - - - Unescape the string escaped in URI encoding format. - - String to be unescape. - Unescaped string. - - - - Escape / Unescape string in URI encoding format - - Charset that is not escaped is represented NonUriChar member. - - NonUriChar = new Regex(@"[^0-9A-Za-z\-_.!~*'()\\;/?:@&=$,\[\]]"); - - Reset(); @@ -1164,62 +2012,6 @@ verbatim_tag = Resolve(tag_handle, tag_name); - - - Converts YamlNode tree into yaml text. - - - - YamlNode node; - YamlPresenter.ToYaml(node); - - YamlNode node1; - YamlNode node2; - YamlNode node3; - YamlPresenter.ToYaml(node1, node2, node3); - - - - - - - object に代入されたクラスや構造体のメンバーに、リフレクションを - 解して簡単にアクセスできるようにしたクラス - - アクセス方法をキャッシュするので、繰り返し使用する場合に高速化が - 期待できる - - - - - Caches ObjectMemberAccessor instances for reuse. - - - - - - 指定した型へのアクセス方法を表すインスタンスを返す - キャッシュに存在すればそれを返す - キャッシュに存在しなければ新しく作って返す - 作った物はキャッシュされる - - クラスまたは構造体を表す型情報 - - - - - メンバ名と Accessor のペアを巡回する - - - - - - メンバへの読み書きを行うことができる - - オブジェクト - メンバの名前 - - Configuration to customize YAML serialization. @@ -2720,937 +3512,6 @@ The number of child nodes of the sequence. - - - class has instance methods and , - with which C# native objects can be converted into / from YAML text without any preparations. - - var serializer = new YamlSerializer(); - object obj = GetObjectToSerialize(); - string yaml = serializer.Serialize(obj); - object restored = serializer.Deserialize(yaml); - Assert.AreEqual(obj, restored); - - - - -

What kind of objects can be serialized?

- - can serialize / deserialize native C# objects of primitive types - (bool, char, int,...), enums, built-in non-primitive types (string, decimal), structures, - classes and arrays of these types. - - - On the other hand, it does not deal with IntPtr (which is a primitive type, though) and - pointer types (void*, int*, ...) because these types are, by their nature, not persistent. - - - - Classes without a default constructor can be deserialized only when the way of activating an instance - is explicitly specified by . - - - - object obj = new object[]{ - null, - "abc", - true, - 1, - (Byte)1, - 1.0, - "1", - new double[]{ 1.1, 2, -3 }, - new string[]{ "def", "ghi", "1" }, - new System.Drawing.Point(1,3), - new System.Drawing.SolidBrush(Color.Blue) - }; - - var serializer = new YamlSerializer(); - string yaml = serializer.Serialize(obj); - // %YAML 1.2 - // --- - // - null - // - abc - // - True - // - 1 - // - !System.Byte 1 - // - !!float 1 - // - "1" - // - !<!System.Double[]%gt; [1.1, 2, -3] - // - !<!System.String[]%gt; - // - def - // - ghi - // - !System.Drawing.Point 1, 3 - // - !System.Drawing.SolidBrush - // Color: Blue - // ... - - object restored; - try { - restored = YamlSerializer.Deserialize(yaml)[0]; - } catch(MissingMethodException) { - // default constructor is missing for SolidBrush - } - - // Let the library know how to activate an instance of SolidBrush. - YamlNode.DefaultConfig.AddActivator<System.Drawing.SolidBrush>( - () => new System.Drawing.SolidBrush(Color.Black /* dummy */)); - - // Then, all the objects can be restored correctly. - restored = serializer.Deserialize(yaml)[0]; - - - A YAML document generated by always have a %YAML directive and - explicit document start ("---") and end ("...") marks. - This allows several documents to be written in a single YAML stream. - - - var yaml = ""; - var serializer = new YamlSerializer(); - yaml += serializer.Serialize("a"); - yaml += serializer.Serialize(1); - yaml += serializer.Serialize(1.1); - // %YAML 1.2 - // --- - // a - // ... - // %YAML 1.2 - // --- - // 1 - // ... - // %YAML 1.2 - // --- - // 1.1 - // ... - - object[] objects = serializer.Deserialize(yaml); - // objects[0] == "a" - // objects[1] == 1 - // objects[2] == 1.1 - - - Since a YAML stream can consist of multiple YAML documents as above, - returns an array of . - - -

Serializing structures and classes

- - For structures and classes, by default, all public fields and public properties are - serialized. Note that protected / private members are always ignored. - -

Serialization methods

- - Readonly value-type members are also ignored because there is no way to - assign a new value to them on deserialization, while readonly class-type members - are serialized. When deserializing, instead of creating a new object and assigning it - to the member, the child members of such class instance are restored independently. - Such a deserializing method is refered to - YamlSerializeMethod.Content. - - - On the other hand, when writeable fields/properties are deserialized, new objects are - created by using the parameters in the YAML description and assiend to the fields/properties. - Such a deserializing method is refered to - YamlSerializeMethod.Assign. Writeable properties can be explicitly specified to use - YamlSerializeMethod.Content method for - deserialization, by adding to its definition. - - - Another type of serializing method is - YamlSerializeMethod.Binary. - This method is only applicable to an array-type field / property that contains - only value-type members. - - If serializing method is specified, - the member is never serialized nor deserialized. - - - public class Test1 - { - public int PublicProp { get; set; } // processed (by assign) - protected int ProtectedProp { get; set; } // Ignored - private int PrivateProp { get; set; } // Ignored - internal int InternalProp { get; set; } // Ignored - - public int PublicField; // processed (by assign) - protected int ProtectedField; // Ignored - private int PrivateField; // Ignored - internal int InternalField; // Ignored - - public List<string> ClassPropByAssign // processed (by assign) - { get; set; } - - public int ReadOnlyValueProp { get; private set; } // Ignored - public List<string> ReadOnlyClassProp // processed (by content) - { get; private set; } - - [YamlSerialize(YamlSerializeMethod.Content)] - public List<string> ClassPropByContent// processed (by content) - { get; set; } - - public int[] IntArrayField = // processed (by assign) - new int[10]; - - [YamlSerialize(YamlSerializeMethod.Binary)] - public int[] IntArrayFieldBinary = // processed (as binary) - new int[100]; - - [YamlSerialize(YamlSerializeMethod.Never)] - public int PublicPropHidden; // Ignored - - public Test1() - { - ClassPropByAssign = new List<string>(); - ReadOnlyClassProp = new List<string>(); - ClassPropByContent = new List<string>(); - } - } - - public void TestPropertiesAndFields1() - { - var test1 = new Test1(); - test1.ClassPropByAssign.Add("abc"); - test1.ReadOnlyClassProp.Add("def"); - test1.ClassPropByContent.Add("ghi"); - var rand = new Random(0); - for ( int i = 0; i < test1.IntArrayFieldBinary.Length; i++ ) - test1.IntArrayFieldBinary[i] = rand.Next(); - - var serializer = new YamlSerializer(); - string yaml = serializer.Serialize(test1); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test1 - // PublicProp: 0 - // ClassPropByAssign: - // Capacity: 4 - // ICollection.Items: - // - abc - // ReadOnlyClassProp: - // Capacity: 4 - // ICollection.Items: - // - def - // ClassPropByContent: - // Capacity: 4 - // ICollection.Items: - // - ghi - // PublicField: 0 - // IntArrayField: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - // IntArrayFieldBinary: |+2 - // Gor1XAwenmhGkU5ib9NxR11LXxp1iYlH5LH4c9hImTitWSB9Z78II2UvXSXV99A79fj6UBn3GDzbIbd9 - // yBDjAyslYm58iGd/NN+tVjuLRCg3cJBo+PWMbIWm9n4AEC0E7LKXWV5HXUNk7I13APEDWFMM/kWTz2EK - // s7LzFw2gBjpKugkmQJqIfinpQ1J1yqhhz/XjA3TBxDBsEuwrD+SNevQSqEC+/KRbwgE6D011ACMeyRt0 - // BOG6ZesRKCtL0YU6tSnLEpgKVBz+R300qD3/W0aZVk+1vHU+auzyGCGUaHCGd6dpRoEhXoIg2m3+AwJX - // EJ37T+TA9BuEPJtyGoq+crQMFQtXj1Zriz3HFbReclLvDdVpZlcOHPga/3+3Y509EHZ7UyT7H1xGeJxn - // eXPrDDb0Ul04MfZb4UYREOfR3HNzNTUYGRsIPUvHOEW7AaoplIfkVQp19DvGBrBqlP2TZ9atlWUHVdth - // 7lIBeIh0wiXxoOpCbQ7qVP9GkioQUrMkOcAJaad3exyZaOsXxznFCA== - // ... - } - - -

Default values of fields and properties

- - is aware of - System.ComponentModel.DefaultValueAttribute. - So, when a member of a structure / class instance has a value that equals to the default value, - the member will not be written in the YAML text. - - It also checkes for the result of ShouldSerializeXXX method. For instance, just before serializing Font - property of some type, bool ShouldSerializeFont() method is called if exists. If the method returns false, - Font property will not be written in the YAML text. ShouldSerializeXXX method can be non-public. - - - using System.ComponentModel; - - public class Test2 - { - [DefaultValue(0)] - public int Default0 = 0; - - [DefaultValue("a")] - public string Defaulta = "a"; - - public int DynamicDefault = 0; - - bool ShouldSerializeDynamicDefault() - { - return Default0 != DynamicDefault; - } - } - - public void TestDefaultValue() - { - var test2 = new Test2(); - var serializer = new YamlSerializer(); - - // All properties have defalut values. - var yaml = serializer.Serialize(test2); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test2 {} - // ... - - test2.Defaulta = "b"; - yaml = serializer.Serialize(test2); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test2 - // Defaulta: b - // ... - - test2.Defaulta = "a"; - var yaml = serializer.Serialize(test2); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test2 {} - // ... - - test2.DynamicDefault = 1; - yaml = serializer.Serialize(test2); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test2 - // DynamicDefault: 1 - // ... - - test2.Default0 = 1; - yaml = serializer.Serialize(test2); - // %YAML 1.2 - // --- - // !YamlSerializerTest.Test2 - // Default0: 1 - // ... - } - - -

Collection classes

- - If an object implements , or - the child objects are serialized as well its other public members. - Pseudproperty ICollection.Items or IDictionary.Entries appears to hold the child objects. - -

Multitime appearance of a same object

- - preserve C# objects' graph structure. Namely, when a same objects are refered to - from several points in the object graph, the structure is correctly described in YAML text and restored objects - preserve the structure. can safely manipulate directly / indirectly self refering - objects, too. - - - public class TestClass - { - public List<TestClass> list = - new List<TestClass>(); - } - - public class ChildClass: TestClass - { - } - - void RecursiveObjectsTest() - { - var a = new TestClass(); - var b = new ChildClass(); - a.list.Add(a); - a.list.Add(a); - a.list.Add(b); - a.list.Add(a); - a.list.Add(b); - b.list.Add(a); - var serializer = new YamlSerializer(); - string yaml = serializer.Serialize(a); - // %YAML 1.2 - // --- - // &A !TestClass - // list: - // Capacity: 8 - // ICollection.Items: - // - *A - // - *A - // - &B !ChildClass - // list: - // Capacity: 4 - // ICollection.Items: - // - *A - // - *A - // - *B - // ... - - var restored = (TestClass)serializer.Deserialize(yaml)[0]; - Assert.IsTrue(restored == restored.list[0]); - Assert.IsTrue(restored == restored.list[1]); - Assert.IsTrue(restored == restored.list[3]); - Assert.IsTrue(restored == restored.list[5]); - Assert.IsTrue(restored.list[2] == restored.list[4]); - } - - - This is not the case if the object is . Same instances of - are repeatedly written in a YAML text and restored as different - instance of when deserialized, unless the content of the string - is extremely long (longer than 999 chars). - - - // 1000 chars - string long_str = - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" + - "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; - string short_str = "12345"; - object obj = new object[] { long_str, long_str, short_str, short_str }; - var serializer = new YamlSerializer(); - string yaml = serializer.Serialize(obj); - // %YAML 1.2 - // --- - // - &A 01234567890123456789012345678901234567890123456789 ... (snip) ... 789 - // - *A - // - "12345" - // - "12345" - // ... - - -

YAML text written / read by

- - When serializing, intelligently uses various YAML 1.2 styles, - namely the block style, flow style, explicit mapping and implicit mapping, to maximize readability - of the YAML stream. - - - [Flags] - enum TestEnum: uint - { - abc = 1, - あいう = 2 - } - - public void TestVariousFormats() - { - var dict = new Dictionary<object, object>(); - dict.Add(new object[] { 1, "a" }, new object()); - object obj = new object[]{ - dict, - null, - "abc", - "1", - "a ", - "- a", - "abc\n", - "abc\ndef\n", - "abc\ndef\nghi", - new double[]{ 1.1, 2, -3, 3.12, 13.2 }, - new int[,] { { 1, 3}, {4, 5}, {10, 1} }, - new string[]{ "jkl", "mno\npqr" }, - new System.Drawing.Point(1,3), - TestEnum.abc, - TestEnum.abc | TestEnum.あいう, - }; - var config = new YamlConfig(); - config.ExplicitlyPreserveLineBreaks = false; - var serializer = new YamlSerializer(config); - string yaml = serializer.Serialize(obj); - - // %YAML 1.2 - // --- - // - !<!System.Collections.Generic.Dictionary%602[[System.Object,...],[System.Object,...]]> - // Keys: {} - // Values: {} - // IDictionary.Entries: - // ? - 1 - // - a - // : !System.Object {} - // - null - // - abc - // - "1" - // - "a " - // - "- a" - // - "abc\n" - // - |+2 - // abc - // def - // - |-2 - // abc - // def - // ghi - // - !<!System.Double[]> [1.1, 2, -3, 3.12, 13.2] - // - !<!System.Int32[,]> [[1, 3], [4, 5], [10, 1]] - // - !<!System.String[]> - // - jkl - // - |-2 - // mno - // pqr - // - !System.Drawing.Point 1, 3 - // - !TestEnum abc - // - !TestEnum abc, あいう - // ... - } - - - When deserializing, accepts any valid YAML 1.2 documents. - TAG directives, comments, flow / block styles, implicit / explicit mappings can be freely used - to express valid C# objects. Namely, the members of the array can be given eighter in a flow style - or in a block style. - - - By default, outputs a YAML stream with line break of "\r\n". - This can be customized either by setting YamlNode.DefaultConfig.LineBreakForOutput or - by giving an instance of to the - constructor. - - - - var serializer = new YamlSerializer(); - var yaml = serializer.Serialize("abc"); - // %YAML 1.2\r\n // line breaks are explicitly shown in this example - // ---\r\n - // abc\r\n - // ...\r\n - - var config = new YamlConfig(); - config.LineBreakForOutput = "\n"; - serializer = new YamlSerializer(config); - var yaml = serializer.Serialize("abc"); - // %YAML 1.2\n - // ---\n - // abc\n - // ...\n - - YamlNode.DefaultConfig.LineBreakForOutput = "\n"; - - var serializer = new YamlSerializer(); - serializer = new YamlSerializer(); - var yaml = serializer.Serialize("abc"); - // %YAML 1.2\n - // ---\n - // abc\n - // ...\n - - -

Line breaks in YAML text

- - By default, line breaks in multi line values are explicitly presented as escaped style. - Although, this makes the resulting YAML stream hard to read, it is necessary to preserve - the exact content of the string because the YAML specification requires that a YAML parser - must normalize evely line break that is not escaped in a YAML document to be a single line - feed "\n" when deserializing. - - In order to have the YAML documents easy to be read, set - YamlConfig.ExplicitlyPreserveLineBreaks - false. Then, the multiline values of will be written in literal style. - - Of course, it makes all the line breaks to be normalized into a single line feeds "\n". - - - var serializer = new YamlSerializer(); - var text = "abc\r\n def\r\nghi\r\n"; - // abc - // def - // ghi - - // By default, line breaks explicitly appears in escaped form. - var yaml = serializer.Serialize(text); - // %YAML 1.2 - // --- - // "abc\r\n\ - // \ def\r\n\ - // ghi\r\n" - // ... - - // Original line breaks are preserved - var restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\r\n def\r\nghi\r\n" - - - YamlNode.DefaultConfig.ExplicitlyPreserveLineBreaks = false; - - // Literal style is easier to be read. - var yaml = serializer.Serialize(text); - // %YAML 1.2 - // --- - // |+2 - // abc - // def - // ghi - // ... - - // Original line breaks are lost. - var restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\n def\nghi\n" - - - This library offers two work arounds for this problem, although both of which - violates the official behavior of a YAML parser defined in the YAML specification. - - One is to set YamlConfig.LineBreakForInput - to be "\r\n". Then, the YAML parser normalizes all line breaks into "\r\n" instead of "\n". - - The other is to set YamlConfig.NormalizeLineBreaks - false. It disables the line break normalization both at output and at input. Namely, the line breaks are - written and read as-is when serialized / deserialized. - - - var serializer = new YamlSerializer(); - - // text with mixed line breaks - var text = "abc\r def\nghi\r\n"; - // abc\r // line breaks are explicitly shown in this example - // def\n - // ghi\r\n - - YamlNode.DefaultConfig.ExplicitlyPreserveLineBreaks = false; - - // By default, all line breaks are normalized to "\r\n" when serialized. - var yaml = serializer.Serialize(text); - // %YAML 1.2\r\n - // ---\r\n - // |+2\r\n - // abc\r\n - // def\r\n - // ghi\r\n - // ...\r\n - - // When deserialized, line breaks are normalized into "\n". - var restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\n def\nghi\n" - - // Line breaks are normalized into "\r\n" instead of "\n". - YamlNode.DefaultConfig.LineBreakForInput = "\r\n"; - restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\r\n def\r\nghi\r\n" - - // Line breaks are written as is, - YamlNode.DefaultConfig.NormalizeLineBreaks = false; - var yaml = serializer.Serialize(text); - // %YAML 1.2\r\n - // ---\r\n - // |+2\r\n - // abc\r - // def\n - // ghi\r\n - // ...\r\n - - // and are read as is. - restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\r def\nghi\r\n" - - // Note that when the line breaks of YAML stream is changed - // between serialization and deserialization, the original - // line breaks are lost. - yaml = yaml.Replace("\r\n", "\n").Replace("\r", "\n"); - restored = (string)serializer.Deserialize(yaml)[0]; - // "abc\n def\nghi\n" - - - It is repeatedly stated that although these two options are useful in many situation, - they makes the YAML parser violate the YAML specification. - -
-
- - - Initialize an instance of that obeys - . - - - - - Initialize an instance of with custom . - - Custom to customize serialization. - - - - Serialize C# object into YAML text. - - Object to be serialized. - YAML text. - - - - Serialize C# object into YAML text and write it into a . - - A to which the YAML text is written. - Object to be serialized. - - - - Serialize C# object into YAML text and write it into a . - - A to which the YAML text is written. - Object to be serialized. - - - - Serialize C# object into YAML text and save it into a file named as . - - A file name to which the YAML text is written. - Object to be serialized. - - - - Deserialize C# object(s) from a YAML text. Since a YAML text can contain multiple YAML documents, each of which - represents a C# object, the result is returned as an array of . - - A YAML text from which C# objects are deserialized. - Expected type(s) of the root object(s) in the YAML stream. - C# object(s) deserialized from YAML text. - - - - Deserialize C# object(s) from a YAML text in a . - Since a YAML text can contain multiple YAML documents, each of which - represents a C# object, the result is returned as an array of . - - A that contains YAML text from which C# objects are deserialized. - Expected type(s) of the root object(s) in the YAML stream. - C# object(s) deserialized from YAML text. - - - - Deserialize C# object(s) from a YAML text in a . - Since a YAML text can contain multiple YAML documents, each of which - represents a C# object, the result is returned as an array of . - - A that contains YAML text from which C# objects are deserialized. - Expected type(s) of the root object(s) in the YAML stream. - C# object(s) deserialized from YAML text. - - - - Deserialize C# object(s) from a YAML text in a file named as . - Since a YAML text can contain multiple YAML documents, each of which - represents a C# object, the result is returned as an array of . - - The name of a file that contains YAML text from which C# objects are deserialized. - Expected type(s) of the root object(s) in the YAML stream. - C# object(s) deserialized from YAML text. - - - - Add .DoFunction method to string - - - - - Short expression of string.Format(XXX, arg1, arg2, ...) - - - - - - - - Specify the way to store a property or field of some class or structure. - See for detail. - - - - - - - The property / field will not be stored. - - - - - When restored, new object is created by using the parameters in - the YAML data and assigned to the property / field. When the - property / filed is writeable, this is the default. - - - - - Only valid for a property / field that has a class or struct type. - When restored, instead of recreating the whole class or struct, - the members are independently restored. When the property / field - is not writeable this is the default. - - - - - Only valid for a property / field that has an array type of a - some value type. The content of the array is stored in a binary - format encoded in base64 style. - - - - - Specify the way to store a property or field of some class or structure. - - See for detail. - - - - - - - Specify the way to store a property or field of some class or structure. - - See for detail. - - - - - - - Never: The property / field will not be stored. - - - - Assign: When restored, new object is created by using the parameters in - the YAML data and assigned to the property / field. When the - property / filed is writeable, this is the default. - - - - Content: Only valid for a property / field that has a class or struct type. - When restored, instead of recreating the whole class or struct, - the members are independently restored. When the property / field - is not writeable this is the default. - - - - Binary: Only valid for a property / field that has an array type of a - some value type. The content of the array is stored in a binary - format encoded in base64 style. - - - - - - Type 関連のユーティリティメソッド - - - - Type type; - AttributeType attr = type.GetAttribute<AttributeType>(); - - PropertyInfo propInfo; - AttributeType attr = propInfo.GetAttribute<AttributeType>(); - - string name; - Type type = TypeUtils.GetType(name); // search from all assembly loaded - - - - - - - - Type や PropertyInfo, FieldInfo から指定された型の属性を取り出して返す - 複数存在した場合には最後の値を返す - 存在しなければ null を返す - - 取り出したい属性の型 - 取り出した属性値 - - - - 現在ロードされているすべてのアセンブリから name という名の型を探して返す - - - - - - - Check if the type is a ValueType and does not contain any non ValueType members. - - - - - - - Returnes true if the specified is a struct type. - - to be analyzed. - true if the specified is a struct type; otehrwise false. - - - - Compare two objects to see if they are equal or not. Null is acceptable. - - - - - - - - Return if an object is a numeric value. - - Any object to be tested. - True if object is a numeric value. - - - - Cast an object to a specified numeric type. - - Any object - Numric type - Numeric value or null if the object is not a numeric value. - - - - Cast boxed numeric value to double - - boxed numeric value - Numeric value in double. Double.Nan if obj is not a numeric value. - - - - Check if type is fully public or not. - Nested class is checked if all declared types are public. - - - - - - - Equality comparer that uses Object.ReferenceEquals(x, y) to compare class values. - - - - - - Determines whether two objects of type T are equal by calling Object.ReferenceEquals(x, y). - - The first object to compare. - The second object to compare. - true if the specified objects are equal; otherwise, false. - - - - Serves as a hash function for the specified object for hashing algorithms and - data structures, such as a hash table. - - The object for which to get a hash code. - A hash code for the specified object. - is null. - - - - Returns a default equality comparer for the type specified by the generic argument. - - The default instance of the System.Collections.Generic.EqualityComparer<T> - class for type T. - - - - Calculate hash code by reference. - - - - - - Initializes a new instance of the HashCodeByRef<T> class. - - - - - Calculate hash code by reference. - - Represents the way to automatically resolve Tag from the Value of a YamlScalar. @@ -3727,6 +3588,22 @@ Decoded value. True if decoded successfully. + + + Converts YamlNode tree into yaml text. + + + + YamlNode node; + YamlPresenter.ToYaml(node); + + YamlNode node1; + YamlNode node2; + YamlNode node3; + YamlPresenter.ToYaml(node1, node2, node3); + + + Extend string object to have .DoubleQuoteEscape() / .DoubleQuoteUnescape(). @@ -3766,5 +3643,112 @@ Unescape control codes, double quotations, backslashes escape in the YAML double quoted string format + + + Add string class two methods: .UriEscape(), .UriUnescape() + + Charset that is not escaped is represented NonUriChar member. + + NonUriChar = new Regex(@"[^0-9A-Za-z\-_.!~*'()\\;/?:@&=$,\[\]]"); + + + + + Escape the string in URI encoding format. + + String to be escaped. + Escaped string. + + + + Escape the string in URI encoding format. + + String to be escaped. + Escaped string. + + + + Unescape the string escaped in URI encoding format. + + String to be unescape. + Unescaped string. + + + + Escape / Unescape string in URI encoding format + + Charset that is not escaped is represented NonUriChar member. + + NonUriChar = new Regex(@"[^0-9A-Za-z\-_.!~*'()\\;/?:@&=$,\[\]]"); + + + + + Dictionary that automatically rehash when the content of a key is changed. + Keys of this dictionary must implement . + It also call back item addition and removal by and + events. + + Type of key. Must implements . + Type of value. + + + + A dictionary that returns or + from hash code. This is the main repository that stores the pairs. + If there are several entries that have same hash code for thir keys, + a is stored to hold all those entries. + Otherwise, a is stored. + + + + + A dictionary that returns hash code from the key reference. + The key must be the instance that + to one exsisting in the dictionary. + + + We store the hashes correspoinding to each key. So that when rehash, + we can find old hash code to quickly find the entry for the key. + It is also used to remember the number of keys exists in the dictionary. + + + + + Recalc hash key of the . + + The key to be rehash. The key must be the instance that + to one exsisting in the dictionary. + + + + Try to find entry for key (and value). + + key to find + if true, value matters + value to find + key not found + hash hit one entry and key found + hash hit several entries and key found + + + + Try to find entry for key (and value). + + key to find + if true, value matters + value to find + hash not found + hash hit one entry but key not found + hash hit one entry and key found + hash hit several entries but key not found + hash hit several entries and key found + + + + Collection that is readonly and invalidated when an item is + added to or removed from the dictionary. + + diff --git a/lib/yaml/YamlSerializer.dll b/lib/yaml/YamlSerializer.dll index 057f2c4e6..74fec4710 100644 Binary files a/lib/yaml/YamlSerializer.dll and b/lib/yaml/YamlSerializer.dll differ diff --git a/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs b/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs index 2b2c5baab..e6c948032 100644 --- a/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs +++ b/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs @@ -50,7 +50,7 @@ namespace Orchard.Azure.Tests.FileSystems.Media { Assert.AreEqual(".txt", storageFile.GetFileType()); Assert.AreEqual("foo.txt", storageFile.GetName()); - Assert.That(storageFile.GetPath().EndsWith("/default/foo.txt"), Is.True); + Assert.AreEqual("foo.txt", storageFile.GetPath()); Assert.AreEqual(0, storageFile.GetSize()); } @@ -71,7 +71,8 @@ namespace Orchard.Azure.Tests.FileSystems.Media { var files = _azureBlobStorageProvider.ListFiles(""); Assert.AreEqual(1, files.Count()); - Assert.That(files.First().GetPath().EndsWith("foo2.txt"), Is.True); + Assert.That(files.First().GetPath().Equals("foo2.txt"), Is.True); + Assert.That(files.First().GetName().Equals("foo2.txt"), Is.True); } [Test] @@ -82,17 +83,28 @@ namespace Orchard.Azure.Tests.FileSystems.Media { Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("").Count()); Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder").Count()); + Assert.AreEqual("folder/foo.txt", _azureBlobStorageProvider.ListFiles("folder").First().GetPath()); + Assert.AreEqual("foo.txt", _azureBlobStorageProvider.ListFiles("folder").First().GetName()); Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder/folder").Count()); + Assert.AreEqual("folder/folder/foo.txt", _azureBlobStorageProvider.ListFiles("folder/folder").First().GetPath()); + Assert.AreEqual("foo.txt", _azureBlobStorageProvider.ListFiles("folder/folder").First().GetName()); } [Test] [ExpectedException(typeof(ArgumentException))] public void CreateFolderThatExistsShouldThrow() { - // sebros: In Azure, the folder concept is just about checking files prefix. So until a file exists, a folder is nothing _azureBlobStorageProvider.CreateFile("folder/foo.txt"); _azureBlobStorageProvider.CreateFolder("folder"); } + [Test] + public void ListFolderShouldAcceptNullPath() { + _azureBlobStorageProvider.CreateFolder("folder"); + Assert.AreEqual(1, _azureBlobStorageProvider.ListFolders(null).Count()); + Assert.AreEqual("folder", _azureBlobStorageProvider.ListFolders(null).First().GetName()); + Assert.AreEqual("folder", _azureBlobStorageProvider.ListFolders(null).First().GetPath()); + } + [Test] public void DeleteFolderShouldDeleteFilesAlso() { _azureBlobStorageProvider.CreateFile("folder/foo1.txt"); diff --git a/src/Orchard.Azure/AzureFileSystem.cs b/src/Orchard.Azure/AzureFileSystem.cs index 6de706353..598974b68 100644 --- a/src/Orchard.Azure/AzureFileSystem.cs +++ b/src/Orchard.Azure/AzureFileSystem.cs @@ -8,11 +8,15 @@ using Microsoft.WindowsAzure.StorageClient; using Orchard.FileSystems.Media; namespace Orchard.Azure { - public class AzureFileSystem { + public class AzureFileSystem + { + private const string FolderEntry = "$$$ORCHARD$$$.$$$"; + public string ContainerName { get; protected set; } private readonly CloudStorageAccount _storageAccount; private readonly string _root; + private readonly string _absoluteRoot; public CloudBlobClient BlobClient { get; private set; } public CloudBlobContainer Container { get; private set; } @@ -25,6 +29,7 @@ namespace Orchard.Azure { _storageAccount = storageAccount; ContainerName = containerName; _root = String.IsNullOrEmpty(root) || root == "/" ? String.Empty : root + "/"; + _absoluteRoot = _storageAccount.BlobEndpoint.AbsoluteUri + containerName + "/" + root + "/"; using ( new HttpContextWeaver() ) { @@ -46,66 +51,65 @@ namespace Orchard.Azure { } private static void EnsurePathIsRelative(string path) { - if ( path.StartsWith("/") || path.StartsWith("http://")) + if (path.StartsWith("/") || path.StartsWith("http://")) throw new ArgumentException("Path must be relative"); } public IStorageFile GetFile(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - using ( new HttpContextWeaver() ) - { - Container.EnsureBlobExists(path); - return new AzureBlobFileStorage(Container.GetBlockBlobReference(path)); + using ( new HttpContextWeaver() ) { + Container.EnsureBlobExists(String.Concat(_root, path)); + return new AzureBlobFileStorage(Container.GetBlockBlobReference(path), _absoluteRoot); } } public bool FileExists(string path) { - using ( new HttpContextWeaver() ) - { - path = String.Concat(_root, path); - return Container.BlobExists(path); + using ( new HttpContextWeaver() ) { + return Container.BlobExists(String.Concat(_root, path)); } } public IEnumerable ListFiles(string path) { + path = path ?? String.Empty; + EnsurePathIsRelative(path); string prefix = String.Concat(Container.Name, "/", _root, path); + if ( !prefix.EndsWith("/") ) prefix += "/"; - using ( new HttpContextWeaver() ) - { - foreach (var blobItem in BlobClient.ListBlobsWithPrefix(prefix).OfType()) - { - yield return new AzureBlobFileStorage(blobItem); + + using ( new HttpContextWeaver() ) { + foreach (var blobItem in BlobClient.ListBlobsWithPrefix(prefix).OfType()) { + // ignore directory entries + if(blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry)) + continue; + + yield return new AzureBlobFileStorage(blobItem, _absoluteRoot); } } } public IEnumerable ListFolders(string path) { + path = path ?? String.Empty; + EnsurePathIsRelative(path); - path = String.Concat(_root, path); - using ( new HttpContextWeaver() ) - { - if (!Container.DirectoryExists(path)) - { - try - { - CreateFolder(path); + using ( new HttpContextWeaver() ) { + if ( !Container.DirectoryExists(String.Concat(_root, path)) ) { + try { + CreateFolder(String.Concat(_root, path)); } - catch (Exception ex) - { + catch ( Exception ex ) { throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", path, ex)); } } - return Container.GetDirectoryReference(path) + return Container.GetDirectoryReference(String.Concat(_root, path)) .ListBlobs() .OfType() - .Select(d => new AzureBlobFolderStorage(d)) + .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot)) .ToList(); } } @@ -113,23 +117,20 @@ namespace Orchard.Azure { public void CreateFolder(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - using (new HttpContextWeaver()) - { - Container.EnsureDirectoryDoesNotExist(path); - Container.GetDirectoryReference(path); + using (new HttpContextWeaver()) { + Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path)); + + // Creating a virtually hidden file to make the directory an existing concept + CreateFile(path + "/" + FolderEntry); } } public void DeleteFolder(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - using ( new HttpContextWeaver() ) - { - Container.EnsureDirectoryExists(path); - foreach (var blob in Container.GetDirectoryReference(path).ListBlobs()) - { + using ( new HttpContextWeaver() ) { + Container.EnsureDirectoryExists(String.Concat(_root, path)); + foreach ( var blob in Container.GetDirectoryReference(String.Concat(_root, path)).ListBlobs() ) { if (blob is CloudBlob) ((CloudBlob) blob).Delete(); @@ -141,7 +142,6 @@ namespace Orchard.Azure { public void RenameFolder(string path, string newPath) { EnsurePathIsRelative(path); - EnsurePathIsRelative(newPath); if ( !path.EndsWith("/") ) @@ -149,20 +149,16 @@ namespace Orchard.Azure { if ( !newPath.EndsWith("/") ) newPath += "/"; - using ( new HttpContextWeaver() ) - { - foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) - { - if (blob is CloudBlob) - { + using ( new HttpContextWeaver() ) { + foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) { + if (blob is CloudBlob) { string filename = Path.GetFileName(blob.Uri.ToString()); string source = String.Concat(path, filename); string destination = String.Concat(newPath, filename); RenameFile(source, destination); } - if (blob is CloudBlobDirectory) - { + if (blob is CloudBlobDirectory) { string foldername = blob.Uri.Segments.Last(); string source = String.Concat(path, foldername); string destination = String.Concat(newPath, foldername); @@ -174,29 +170,24 @@ namespace Orchard.Azure { public void DeleteFile(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - - using ( new HttpContextWeaver() ) - { + + using ( new HttpContextWeaver() ) { Container.EnsureBlobExists(path); - var blob = Container.GetBlockBlobReference(path); + var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); blob.Delete(); } } public void RenameFile(string path, string newPath) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - EnsurePathIsRelative(newPath); - newPath = String.Concat(_root, newPath); - using ( new HttpContextWeaver() ) - { - Container.EnsureBlobExists(path); - Container.EnsureBlobDoesNotExist(newPath); - var blob = Container.GetBlockBlobReference(path); - var newBlob = Container.GetBlockBlobReference(newPath); + using ( new HttpContextWeaver() ) { + Container.EnsureBlobExists(String.Concat(_root, path)); + Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath)); + + var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); + var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath)); newBlob.CopyFromBlob(blob); blob.Delete(); } @@ -204,36 +195,36 @@ namespace Orchard.Azure { public IStorageFile CreateFile(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - if ( Container.BlobExists(path) ) { + if ( Container.BlobExists(String.Concat(_root, path)) ) { throw new ArgumentException("File " + path + " already exists"); } - var blob = Container.GetBlockBlobReference(path); + var blob = Container.GetBlockBlobReference(String.Concat(_root, path)); blob.OpenWrite().Dispose(); // force file creation - return new AzureBlobFileStorage(blob); + return new AzureBlobFileStorage(blob, _absoluteRoot); } public string GetPublicUrl(string path) { EnsurePathIsRelative(path); - path = String.Concat(_root, path); - using ( new HttpContextWeaver() ) - { - Container.EnsureBlobExists(path); - return Container.GetBlockBlobReference(path).Uri.ToString(); + + using ( new HttpContextWeaver() ) { + Container.EnsureBlobExists(String.Concat(_root, path)); + return Container.GetBlockBlobReference(String.Concat(_root, path)).Uri.ToString(); } } private class AzureBlobFileStorage : IStorageFile { private readonly CloudBlockBlob _blob; + private readonly string _rootPath; - public AzureBlobFileStorage(CloudBlockBlob blob) { + public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) { _blob = blob; + _rootPath = rootPath; } public string GetPath() { - return _blob.Uri.ToString(); + return _blob.Uri.ToString().Substring(_rootPath.Length+1); } public string GetName() { @@ -264,17 +255,19 @@ namespace Orchard.Azure { private class AzureBlobFolderStorage : IStorageFolder { private readonly CloudBlobDirectory _blob; + private readonly string _rootPath; - public AzureBlobFolderStorage(CloudBlobDirectory blob) { + public AzureBlobFolderStorage(CloudBlobDirectory blob, string rootPath) { _blob = blob; + _rootPath = rootPath; } public string GetName() { - return Path.GetDirectoryName(_blob.Uri.ToString()); + return Path.GetDirectoryName(GetPath() + "/"); } public string GetPath() { - return _blob.Uri.ToString(); + return _blob.Uri.ToString().Substring(_rootPath.Length + 1).TrimEnd('/'); } public long GetSize() { @@ -287,7 +280,7 @@ namespace Orchard.Azure { public IStorageFolder GetParent() { if ( _blob.Parent != null ) { - return new AzureBlobFolderStorage(_blob.Parent); + return new AzureBlobFolderStorage(_blob.Parent, _rootPath); } throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory"); } diff --git a/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs b/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs index 832917606..ad0306387 100644 --- a/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs +++ b/src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs @@ -8,6 +8,11 @@ namespace Orchard.Azure.Web { public override bool OnStart() { DiagnosticMonitor.Start("DiagnosticsConnectionString"); + CloudStorageAccount.SetConfigurationSettingPublisher( + (configName, configSetter) => + configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) + ); + // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. RoleEnvironment.Changing += RoleEnvironmentChanging; diff --git a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs index ae9e5661b..ad47314a4 100644 --- a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs +++ b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs @@ -21,6 +21,7 @@ using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.Environment; using Orchard.Environment.Extensions; +using Orchard.Mvc; using Orchard.Security; using Orchard.Tests.Modules; using System.Web.Mvc; @@ -45,6 +46,8 @@ namespace Orchard.Core.Tests.Routable.Services { builder.RegisterInstance(new Mock().Object); builder.RegisterInstance(new Mock().Object); builder.RegisterInstance(new Mock().Object); + builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config b/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config index f2f307586..dd900f1a0 100644 --- a/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config +++ b/src/Orchard.Specs/Hosting/Orchard.Web/Themes/Web.config @@ -2,9 +2,6 @@ - - - + + + diff --git a/src/Orchard.Web/Core/Contents/Settings/ContentTypeSettings.cs b/src/Orchard.Web/Core/Contents/Settings/ContentTypeSettings.cs index e0d35b2e9..ed495eab7 100644 --- a/src/Orchard.Web/Core/Contents/Settings/ContentTypeSettings.cs +++ b/src/Orchard.Web/Core/Contents/Settings/ContentTypeSettings.cs @@ -1,8 +1,12 @@ namespace Orchard.Core.Contents.Settings { public class ContentTypeSettings { /// - /// This setting is used to display a Content Type in Content Management menu like + /// Used to determine if an instance of this content type can be created through the UI /// public bool Creatable { get; set; } + /// + /// Used to determine if this content type supports draft versions + /// + public bool Draftable { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Views/Content.PublishButton.cshtml b/src/Orchard.Web/Core/Contents/Views/Content.PublishButton.cshtml new file mode 100644 index 000000000..b8f48a08f --- /dev/null +++ b/src/Orchard.Web/Core/Contents/Views/Content.PublishButton.cshtml @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Views/Content.SaveButton.cshtml b/src/Orchard.Web/Core/Contents/Views/Content.SaveButton.cshtml new file mode 100644 index 000000000..cab18005a --- /dev/null +++ b/src/Orchard.Web/Core/Contents/Views/Content.SaveButton.cshtml @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml b/src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml index e0f0cd87b..534856f87 100644 --- a/src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml +++ b/src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml @@ -1,12 +1,21 @@ -
-
- @Display(Model.Content) +
+
+ @if (Model.Content != null) { +
+ @Display(Model.Content) +
+ }
-
- @Display(Model.Sidebar) - @* todo: (heskew) remove when the CommonPart is adding the save button *@ -
- -
+
+ @if (Model.Actions != null) { +
+ @Display(Model.Actions) +
+ } + @if (Model.Sidebar != null) { +
+ @Display(Model.Sidebar) +
+ }
\ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Views/Web.config b/src/Orchard.Web/Core/Contents/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Core/Contents/Views/Web.config +++ b/src/Orchard.Web/Core/Contents/Views/Web.config @@ -2,8 +2,6 @@ - - + diff --git a/src/Orchard.Web/Core/Localization/Styles/Web.config b/src/Orchard.Web/Core/Localization/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Core/Localization/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Localization/Styles/admin.css b/src/Orchard.Web/Core/Localization/Styles/admin.css index 1eab4b11d..a1b831c00 100644 --- a/src/Orchard.Web/Core/Localization/Styles/admin.css +++ b/src/Orchard.Web/Core/Localization/Styles/admin.css @@ -1,10 +1,6 @@ .summary .content-localization { margin: .7em 0; } -.content-localization .content-localizations li, -.content-localization .add-localization { - font-size:1.4em; -} .content-localization .culture-selected { margin-bottom:.5em; } diff --git a/src/Orchard.Web/Core/Localization/Views/Web.config b/src/Orchard.Web/Core/Localization/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Core/Localization/Views/Web.config +++ b/src/Orchard.Web/Core/Localization/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Routable/Views/Web.config b/src/Orchard.Web/Core/Routable/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Core/Routable/Views/Web.config +++ b/src/Orchard.Web/Core/Routable/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Settings/Views/Admin/Index.cshtml b/src/Orchard.Web/Core/Settings/Views/Admin/Index.cshtml index a83d7786c..b1504ef3c 100644 --- a/src/Orchard.Web/Core/Settings/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Core/Settings/Views/Admin/Index.cshtml @@ -3,7 +3,6 @@ @Html.ValidationSummary() @Display(Model.Content)
- +
-} - +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts/Settings.SiteSettingsPart.cshtml b/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts/Settings.SiteSettingsPart.cshtml index 911c048ff..54b425f75 100644 --- a/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts/Settings.SiteSettingsPart.cshtml +++ b/src/Orchard.Web/Core/Settings/Views/EditorTemplates/Parts/Settings.SiteSettingsPart.cshtml @@ -33,6 +33,6 @@
@Html.DropDownList("ResourceDebugMode", resourceDebugMode) -

@T("Determines whether scripts and stylesheets load in their debuggable or minified form.")

+ @T("Determines whether scripts and stylesheets load in their debuggable or minified form.")
\ No newline at end of file diff --git a/src/Orchard.Web/Core/Settings/Views/Web.config b/src/Orchard.Web/Core/Settings/Views/Web.config index bf2230060..dd900f1a0 100644 --- a/src/Orchard.Web/Core/Settings/Views/Web.config +++ b/src/Orchard.Web/Core/Settings/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Shapes/Scripts/base.js b/src/Orchard.Web/Core/Shapes/Scripts/base.js index 41a34f23c..1ec08c2fb 100644 --- a/src/Orchard.Web/Core/Shapes/Scripts/base.js +++ b/src/Orchard.Web/Core/Shapes/Scripts/base.js @@ -85,15 +85,48 @@ var firstError = _this.find(".input-validation-error").first(); // try to focus the first error on the page if (firstError.size() === 1) { - return firstError.focus(); + firstError.focus(); + return _this; } // or, give it up to the browser to autofocus if ('autofocus' in document.createElement('input')) { - return; + return _this; } // otherwise, make the autofocus attribute work var autofocus = _this.find(":input[autofocus]").first(); - return autofocus.focus(); + autofocus.focus(); + + return _this; + }, + helpfullyPlacehold: function () { + var _this = $(this); + + // give it up to the browser to handle placeholder text + if ('placeholder' in document.createElement('input')) { + return _this; + } + // otherwise, make the placeholder attribute work + $(":input[placeholder]") + .each(function () { + var _this = $(this); + if (_this.val() === "") { + _this.val(_this.attr("placeholder")).addClass("placeholderd"); + } + }) + .live("focus", function () { + var _this = $(this); + if (_this.val() === _this.attr("placeholder")) { + _this.val("").removeClass("placeholderd"); + } + }) + .live("blur", function () { + var _this = $(this); + if (_this.val() === "") { + _this.val(_this.attr("placeholder")).addClass("placeholderd"); + } + }); + + return _this; }, toggleWhatYouControl: function () { var _this = $(this); @@ -103,14 +136,14 @@ _controllees.hide(); // <- unhook this when the following comment applies $(_controllees.show()[0]).find("input").focus(); // <- aaaand a slideDown there...eventually } else if (!(_this.is(":checked") && _controlleesAreHidden)) { - //_controllees.slideUp(200); <- hook this back up when chrome behaves, or when I care less + //_controllees.slideUp(200); <- hook this back up when chrome behaves, or when I care less...or when chrome behaves _controllees.hide() } - return this; + return _this; } }); // collapsable areas - anything with a data-controllerid attribute has its visibility controlled by the id-ed radio/checkbox - (function () { + $(function () { $("[data-controllerid]").each(function () { var controller = $("#" + $(this).attr("data-controllerid")); if (controller.data("isControlling")) { @@ -126,9 +159,9 @@ $("[name=" + controller.attr("name") + "]").click(function () { $("[name=" + $(this).attr("name") + "]").each($(this).toggleWhatYouControl); }); } }); - })(); + }); // inline form link buttons (form.inline.link button) swapped out for a link that submits said form - (function () { + $(function () { $("form.inline.link").each(function () { var _this = $(this); var link = $(""); @@ -141,10 +174,12 @@ _this.css({ "position": "absolute", "left": "-9999em" }); $("body").append(_this); }); - })(); - // (do) a little better autofocus + }); + // some default value add behavior $(function () { - $("body").helpfullyFocus(); + $("body").helpfullyFocus() // (do) a little better autofocus + .helpfullyPlacehold(); // pick up on placeholders + }); // UnsafeUrl links -> form POST //todo: need some real microdata support eventually (incl. revisiting usage of data-* attributes) diff --git a/src/Orchard.Web/Core/Shapes/Styles/Web.config b/src/Orchard.Web/Core/Shapes/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Core/Shapes/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Shapes/Views/UI/Switchable.cshtml b/src/Orchard.Web/Core/Shapes/Views/UI/Switchable.cshtml deleted file mode 100644 index 8f3d5b92c..000000000 --- a/src/Orchard.Web/Core/Shapes/Views/UI/Switchable.cshtml +++ /dev/null @@ -1,5 +0,0 @@ -@{ - Style.Require("Switchable"); - Script.Require("Switchable"); -} -@string.Format("{0} switchable", Model) \ No newline at end of file diff --git a/src/Orchard.Web/Core/Shapes/Views/Web.config b/src/Orchard.Web/Core/Shapes/Views/Web.config index bf2230060..dd900f1a0 100644 --- a/src/Orchard.Web/Core/Shapes/Views/Web.config +++ b/src/Orchard.Web/Core/Shapes/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Lucene/Lucene.csproj b/src/Orchard.Web/Modules/Lucene/Lucene.csproj index 51d46bd9f..df287dfec 100644 --- a/src/Orchard.Web/Modules/Lucene/Lucene.csproj +++ b/src/Orchard.Web/Modules/Lucene/Lucene.csproj @@ -80,9 +80,6 @@ - - - {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} diff --git a/src/Orchard.Web/Modules/Lucene/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Lucene/Properties/AssemblyInfo.cs index 5af5bac30..d65524200 100644 --- a/src/Orchard.Web/Modules/Lucene/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Lucene/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -33,3 +33,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Lucene/Web.config b/src/Orchard.Web/Modules/Lucene/Web.config deleted file mode 100644 index 489780384..000000000 --- a/src/Orchard.Web/Modules/Lucene/Web.config +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Content/Web.config b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Content/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Content/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Orchard.ArchiveLater.csproj b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Orchard.ArchiveLater.csproj index d63ddfbbf..8e940f29b 100644 --- a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Orchard.ArchiveLater.csproj +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Orchard.ArchiveLater.csproj @@ -106,6 +106,16 @@ Designer + + + Designer + + + + + Designer + + + + +
+ + + + + + +
diff --git a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/Web.config b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/Web.config index 1295710ba..9a4455a74 100644 --- a/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.ArchiveLater/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj index 1b1b04662..ab2642930 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Orchard.Blogs.csproj @@ -135,7 +135,6 @@ Code - @@ -159,10 +158,18 @@ - + + Designer + + + Designer + + + Designer + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Properties/AssemblyInfo.cs index 5f140ddc6..6c556e74a 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -32,3 +32,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Scripts/Web.config b/src/Orchard.Web/Modules/Orchard.Blogs/Scripts/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Scripts/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.Blogs/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.DetailAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.DetailAdmin.cshtml index 83169a11b..b702306f0 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.DetailAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.DetailAdmin.cshtml @@ -1,6 +1,6 @@ @using Orchard.Blogs.Extensions; @using Orchard.Blogs.Models; -

@Html.TitleForPage((string)Model.Title)

+

@Html.TitleForPage((string)Model.Title)

@Display(Model.Header) @Display(Model.Actions) diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.Edit.cshtml index 92f5bf5b8..dbb1e6cc7 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.Edit.cshtml @@ -2,13 +2,24 @@ @{ Html.AddTitleParts((string)Model.Title); } -
-
- @Display(Model.Content) +
+
+ @if (Model.Content != null) { +
+ @Display(Model.Content) +
+ }
-
- @Display(Model.Sidebar) - @* todo: (heskew) remove when the CommonPart is adding the save button *@ -
+
+ @if (Model.Actions != null) { +
+ @Display(Model.Actions) +
+ } + @if (Model.Sidebar != null) { +
+ @Display(Model.Sidebar) +
+ }
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.SummaryAdmin.cshtml index 63bce04f0..021cd18a0 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-Blog.SummaryAdmin.cshtml @@ -3,8 +3,9 @@ @using Orchard.ContentManagement; @using Orchard.Utility.Extensions; @{ - ContentItem contentItem = Model.ContentItem; - var returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString(); + Script.Require("ShapesBase"); + ContentItem contentItem = Model.ContentItem; + var returnUrl = ViewContext.RequestContext.HttpContext.Request.ToUrlString(); }
diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-BlogPost.Editor.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-BlogPost.Editor.cshtml deleted file mode 100644 index a73373f4f..000000000 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Items/Content-BlogPost.Editor.cshtml +++ /dev/null @@ -1,23 +0,0 @@ -@* todo: (heskew) remove - not being used but keeping around for the "remove draft" reminder *@ - -@using Orchard.Blogs.Models; -@{ - Html.AddTitleParts((string)Model.Title); - BlogPostPart blogPost = Model.ContentItem.Get(typeof(BlogPostPart)); -} -
-
- @Display(Model.Content) -
-
- @Display(Model.Sidebar) - @* todo: (heskew) remove when the CommonPart is adding the save button - also move the remove draft functionality to the CommonPart at that time *@ -
- - @* TODO: (erikpo) In the future, remove the HasPublished check so the user can delete the content item from here if the choose to *@ - @if (blogPost.HasDraft && blogPost.HasPublished) { - @Html.AntiForgeryTokenValueOrchardLink(T("Discard Draft").ToString(), Url.Action("DiscardDraft", new {Area = "Orchard.Blogs", Controller = "BlogPostAdmin", id = Model.Item.Id}), new {@class = "button"}) - } -
-
-
asdfsdaf \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Web.config index bf2230060..dd900f1a0 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt index 7022197d4..260e8318d 100644 --- a/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt +++ b/src/Orchard.Web/Modules/Orchard.CodeGeneration/CodeGenerationTemplates/ViewsWebConfig.txt @@ -2,8 +2,6 @@ - - - - - - - - - - - - - - - - diff --git a/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/EditorTemplates/Parts/ContentQueries.Configuration.cshtml b/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/EditorTemplates/Parts/ContentQueries.Configuration.cshtml deleted file mode 100644 index 0028f00f6..000000000 --- a/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/EditorTemplates/Parts/ContentQueries.Configuration.cshtml +++ /dev/null @@ -1 +0,0 @@ -

content query config here -> x

\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/Parts/QueriedContents.cshtml b/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/Parts/QueriedContents.cshtml deleted file mode 100644 index ac6ffaa9a..000000000 --- a/src/Orchard.Web/Modules/Orchard.ContentQueries/Views/Parts/QueriedContents.cshtml +++ /dev/null @@ -1,14 +0,0 @@ -@{ - IEnumerable queriedContents = Model.ContentItems; - Model.ContentItems.Classes.Add("content-items"); - Model.ContentItems.Classes.Add("queried-contents"); -} -@if (queriedContents != null && queriedContents.Count() > 0) { - @Display(Model.ContentItems) - if (Model.Pager != null) { - @Display(Model.Pager) - } -} -else { -

@T("There are no contents.")

-} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentQueries/Web.config b/src/Orchard.Web/Modules/Orchard.ContentQueries/Web.config deleted file mode 100644 index aeb6287ed..000000000 --- a/src/Orchard.Web/Modules/Orchard.ContentQueries/Web.config +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj index 0dfae91f7..48430edc9 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Orchard.ContentTypes.csproj @@ -117,16 +117,13 @@ - - - Web.config - - - Web.config - - + + + Designer + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Properties/AssemblyInfo.cs index 2b4b7e096..04092a77f 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -33,3 +33,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs index d81c09df1..9c3d936af 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Services/ContentDefinitionService.cs @@ -73,7 +73,8 @@ namespace Orchard.ContentTypes.Services { var contentTypeDefinition = new ContentTypeDefinition(name, typeViewModel.DisplayName); _contentDefinitionManager.StoreTypeDefinition(contentTypeDefinition); - _contentDefinitionManager.AlterTypeDefinition(name, cfg => cfg.Creatable()); + _contentDefinitionManager.AlterTypeDefinition(name, + cfg => cfg.Creatable().Draftable()); return new EditTypeViewModel(contentTypeDefinition); } diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.ContentTypes/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddFieldTo.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddFieldTo.cshtml index f71dffd64..f9a849799 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddFieldTo.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddFieldTo.cshtml @@ -1,6 +1,7 @@ @model Orchard.ContentTypes.ViewModels.AddFieldViewModel @{ Style.Require("ContentTypesAdmin"); } -

@Html.TitleForPage(T("Add New Field To \"{0}\"", Model.Part.DisplayName).ToString())

@using (Html.BeginFormAntiForgeryPost()) { +

@Html.TitleForPage(T("Add New Field To \"{0}\"", Model.Part.DisplayName).ToString())

+@using (Html.BeginFormAntiForgeryPost()) { @Html.ValidationSummary()
@@ -12,4 +13,5 @@
-
} + +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddPartsTo.cshtml b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddPartsTo.cshtml index e2335d8bb..ca6f5f08e 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddPartsTo.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Admin/AddPartsTo.cshtml @@ -1,6 +1,7 @@ @model Orchard.ContentTypes.ViewModels.AddPartsViewModel @{ Style.Require("ContentTypesAdmin"); } -

@Html.TitleForPage(T("Add Parts To \"{0}\"", Model.Type.DisplayName).ToString())

@using (Html.BeginFormAntiForgeryPost()) { +

@Html.TitleForPage(T("Add Parts To \"{0}\"", Model.Type.DisplayName).ToString())

+@using (Html.BeginFormAntiForgeryPost()) { @Html.ValidationSummary()
@Html.UnorderedList( @@ -19,4 +20,5 @@
-
} + +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Web.config b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Web.config index 3e2ccce91..271dd8ba1 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.ContentTypes/Views/Web.config @@ -3,7 +3,6 @@ - - - - - - - - \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.Release.config b/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.Release.config deleted file mode 100644 index 141832ba7..000000000 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.Release.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.config b/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.config deleted file mode 100644 index cf1174676..000000000 --- a/src/Orchard.Web/Modules/Orchard.ContentTypes/Web.config +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj b/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj index fc2743ca7..4573ff0b0 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj +++ b/src/Orchard.Web/Modules/Orchard.Email/Orchard.Email.csproj @@ -78,7 +78,6 @@
- @@ -99,7 +98,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.Email/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.Email/Properties/AssemblyInfo.cs index b48379f8b..73f6dc1af 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.Email/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -32,4 +31,4 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] -[assembly: AssemblyFileVersion("0.8.0")] +[assembly: AssemblyFileVersion("0.8.0")] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessagingChannel.cs b/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessagingChannel.cs index ddff31e2a..2992fcc0d 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessagingChannel.cs +++ b/src/Orchard.Web/Modules/Orchard.Email/Services/EmailMessagingChannel.cs @@ -2,25 +2,24 @@ using System.Collections.Generic; using System.Net; using System.Net.Mail; -using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.Localization; using Orchard.Logging; using Orchard.Email.Models; -using Orchard.Settings; using Orchard.Messaging.Services; using Orchard.Messaging.Models; namespace Orchard.Email.Services { public class EmailMessagingChannel : IMessagingChannel { + private readonly IOrchardServices _orchardServices; public const string EmailService = "Email"; - public EmailMessagingChannel() { + public EmailMessagingChannel(IOrchardServices orchardServices) { + _orchardServices = orchardServices; Logger = NullLogger.Instance; } - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } public ILogger Logger { get; set; } public Localizer T { get; set; } @@ -28,7 +27,7 @@ namespace Orchard.Email.Services { if ( !context.Service.Equals(EmailService, StringComparison.InvariantCultureIgnoreCase) ) return; - var smtpSettings = CurrentSite.As(); + var smtpSettings = _orchardServices.WorkContext.CurrentSite.As(); // can't process emails if the Smtp settings have not yet been set if ( smtpSettings == null || !smtpSettings.IsValid() ) { diff --git a/src/Orchard.Web/Modules/Orchard.Email/Services/MissingSettingsBanner.cs b/src/Orchard.Web/Modules/Orchard.Email/Services/MissingSettingsBanner.cs index d35cbe328..f124e1f10 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Services/MissingSettingsBanner.cs +++ b/src/Orchard.Web/Modules/Orchard.Email/Services/MissingSettingsBanner.cs @@ -1,33 +1,32 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.Core.Messaging.Models; using Orchard.Localization; using Orchard.Email.Models; -using Orchard.Settings; using Orchard.UI.Admin.Notification; using Orchard.UI.Notify; namespace Orchard.Email.Services { public class MissingSettingsBanner: INotificationProvider { + private readonly IOrchardServices _orchardServices; - public MissingSettingsBanner() { + public MissingSettingsBanner(IOrchardServices orchardServices) { + _orchardServices = orchardServices; T = NullLocalizer.Instance; } - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } public Localizer T { get; set; } public IEnumerable GetNotifications() { - var smtpSettings = CurrentSite.As(); + var smtpSettings = _orchardServices.WorkContext.CurrentSite.As(); if ( smtpSettings == null || !smtpSettings.IsValid() ) { yield return new NotifyEntry { Message = T("The SMTP settings needs to be configured." ), Type = NotifyType.Warning}; } - var messageSettings = CurrentSite.As().Record; + var messageSettings = _orchardServices.WorkContext.CurrentSite.As().Record; if ( messageSettings == null || String.IsNullOrWhiteSpace(messageSettings.DefaultChannelService) ) { yield return new NotifyEntry { Message = T("The default channel service needs to be configured."), Type = NotifyType.Warning }; diff --git a/src/Orchard.Web/Modules/Orchard.Email/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Email/Views/Web.config index e065d8735..f7f177dd6 100644 --- a/src/Orchard.Web/Modules/Orchard.Email/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Email/Views/Web.config @@ -2,8 +2,6 @@ - + + + $(ProjectDir)\..\Manifests + + + + + + + False True - 57372 + 45979 / @@ -101,11 +127,4 @@ - \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.ContentQueries/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.Lists/Properties/AssemblyInfo.cs similarity index 79% rename from src/Orchard.Web/Modules/Orchard.ContentQueries/Properties/AssemblyInfo.cs rename to src/Orchard.Web/Modules/Orchard.Lists/Properties/AssemblyInfo.cs index 471617b95..0f2e0ed79 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentQueries/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.Lists/Properties/AssemblyInfo.cs @@ -1,14 +1,13 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Orchard.ContentQueries")] +[assembly: AssemblyTitle("Orchard.Lists")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Orchard")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] @@ -20,7 +19,7 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0003600f-7634-43b0-9a63-68ee7c247db3")] +[assembly: Guid("932b5865-c186-4182-9e79-5a10e59ea685")] // Version information for an assembly consists of the following four values: // @@ -31,5 +30,5 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.8.0")] -[assembly: AssemblyFileVersion("0.8.0")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Scripts/Web.config b/src/Orchard.Web/Modules/Orchard.Lists/Scripts/Web.config new file mode 100644 index 000000000..41ceda512 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Lists/Scripts/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.Lists/Styles/Web.config new file mode 100644 index 000000000..41ceda512 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Lists/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Lists/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Lists/Views/Web.config new file mode 100644 index 000000000..f7f177dd6 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Lists/Views/Web.config @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Web.config b/src/Orchard.Web/Modules/Orchard.Lists/Web.config similarity index 57% rename from src/Orchard.Web/Modules/Orchard.Blogs/Web.config rename to src/Orchard.Web/Modules/Orchard.Lists/Web.config index cf1174676..84e1e66cb 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Lists/Web.config @@ -1,10 +1,9 @@ - - + @@ -21,12 +20,4 @@ - - - - - - - - diff --git a/src/Orchard.Web/Modules/Orchard.Media/Content/Web.config b/src/Orchard.Web/Modules/Orchard.Media/Content/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Content/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs index 42be7e649..14d2898fe 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Media/Controllers/AdminController.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.IO; using System.Web; using System.Web.Mvc; +using JetBrains.Annotations; +using Orchard.ContentManagement; using Orchard.Localization; using Orchard.Media.Models; using Orchard.Media.Services; using Orchard.Media.ViewModels; +using Orchard.Settings; using Orchard.UI.Notify; using Orchard.Utility.Extensions; @@ -153,6 +156,15 @@ namespace Orchard.Media.Controllers { if (!ModelState.IsValid) return View(viewModel); + // first validate them all + foreach (string fileName in Request.Files) { + HttpPostedFileBase file = Request.Files[fileName]; + if (!_mediaService.FileAllowed(file)) { + ModelState.AddModelError("File", T("That file type is not allowed.").ToString()); + return View(viewModel); + } + } + // then save them foreach (string fileName in Request.Files) { HttpPostedFileBase file = Request.Files[fileName]; _mediaService.UploadMediaFile(viewModel.MediaPath, file); @@ -195,10 +207,11 @@ namespace Orchard.Media.Controllers { } } - public ActionResult EditMedia(string name, string caption, DateTime lastUpdated, long size, string folderName, string mediaPath) { + public ActionResult EditMedia(string name, DateTime lastUpdated, long size, string folderName, string mediaPath) { var model = new MediaItemEditViewModel(); model.Name = name; - model.Caption = caption ?? String.Empty; + // todo: reimplement + //model.Caption = caption ?? String.Empty; model.LastUpdated = lastUpdated; model.Size = size; model.FolderName = folderName; diff --git a/src/Orchard.Web/Modules/Orchard.Media/Extensions/LongExtensions.cs b/src/Orchard.Web/Modules/Orchard.Media/Extensions/LongExtensions.cs new file mode 100644 index 000000000..3e5adc860 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Extensions/LongExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; + +namespace Orchard.Media.Extensions { + public static class LongExtensions { + private static List units = new List(5) {"B", "KB", "MB", "GB", "TB"}; // Not going further. Anything beyond MB is probably overkill anyway. + + public static string ToFriendlySizeString(this long bytes) { + var somethingMoreFriendly = TryForTheNextUnit(bytes, units[0]); + var roundingPlaces = units[0] == somethingMoreFriendly.Item2 ? 0 : units.IndexOf(somethingMoreFriendly.Item2) - 1; + return string.Format("{0} {1}", Math.Round(somethingMoreFriendly.Item1, roundingPlaces), somethingMoreFriendly.Item2); + } + + private static Tuple TryForTheNextUnit(double size, string unit) { + var indexOfUnit = units.IndexOf(unit); + + if (size > 1024 && indexOfUnit < units.Count - 1) { + size = size/1024; + unit = units[indexOfUnit + 1]; + return TryForTheNextUnit(size, unit); + } + + return new Tuple(size, unit); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Handlers/MediaSettingsPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Media/Handlers/MediaSettingsPartHandler.cs new file mode 100644 index 000000000..dd480a4c9 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Handlers/MediaSettingsPartHandler.cs @@ -0,0 +1,15 @@ +using JetBrains.Annotations; +using Orchard.Data; +using Orchard.ContentManagement.Handlers; +using Orchard.Media.Models; + +namespace Orchard.Media.Handlers { + [UsedImplicitly] + public class MediaSettingsPartHandler : ContentHandler { + public MediaSettingsPartHandler(IRepository repository) { + Filters.Add(new ActivatingFilter("Site")); + Filters.Add(StorageFilter.For(repository)); + Filters.Add(new TemplateFilterForRecord("MediaSettings", "Parts/Media.MediaSettings")); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Media/Migrations.cs new file mode 100644 index 000000000..0830945b6 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Migrations.cs @@ -0,0 +1,16 @@ +using Orchard.Data.Migration; +using Orchard.Media.Models; + +namespace Orchard.Media { + public class MediaDataMigration : DataMigrationImpl { + public int Create() { + SchemaBuilder.CreateTable("MediaSettingsPartRecord", + table => table + .ContentPartRecord() + .Column("UploadAllowedFileTypeWhitelist", c => c.WithDefault(MediaSettingsPartRecord.DefaultWhitelist).WithLength(255)) + ); + + return 1; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs new file mode 100644 index 000000000..39228bf9c --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPart.cs @@ -0,0 +1,11 @@ +using Orchard.ContentManagement; +using System; + +namespace Orchard.Media.Models { + public class MediaSettingsPart : ContentPart { + public string UploadAllowedFileTypeWhitelist { + get { return Record.UploadAllowedFileTypeWhitelist; } + set { Record.UploadAllowedFileTypeWhitelist = value; } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs new file mode 100644 index 000000000..758732576 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Models/MediaSettingsPartRecord.cs @@ -0,0 +1,16 @@ +using System.Net.Mail; +using Orchard.ContentManagement.Records; +using System.ComponentModel.DataAnnotations; + +namespace Orchard.Media.Models { + public class MediaSettingsPartRecord : ContentPartRecord { + internal const string DefaultWhitelist = "jpg jpeg gif png txt doc docx xls xlsx pdf ppt pptx pps ppsx odt ods odp"; + private string _whitelist = DefaultWhitelist; + + [StringLength(255)] + public virtual string UploadAllowedFileTypeWhitelist { + get { return _whitelist; } + set { _whitelist = value; } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Orchard.Media.csproj b/src/Orchard.Web/Modules/Orchard.Media/Orchard.Media.csproj index 510d90e22..0b80dcc5e 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Orchard.Media.csproj +++ b/src/Orchard.Web/Modules/Orchard.Media/Orchard.Media.csproj @@ -71,6 +71,11 @@ + + + + + @@ -92,7 +97,6 @@ - @@ -114,6 +118,17 @@
+ + + + Designer + + + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Media/ViewModels/MediaItemAddViewModel.cs b/src/Orchard.Web/Modules/Orchard.Media/ViewModels/MediaItemAddViewModel.cs index b71641e71..eadef0eff 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/ViewModels/MediaItemAddViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Media/ViewModels/MediaItemAddViewModel.cs @@ -1,4 +1,6 @@ -namespace Orchard.Media.ViewModels { +using Orchard.Media.Models; + +namespace Orchard.Media.ViewModels { public class MediaItemAddViewModel { public string FolderName { get; set; } public string MediaPath { get; set; } diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml index cb660e72e..81ecc38c4 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Add.cshtml @@ -22,7 +22,7 @@
- + @Html.AntiForgeryTokenOrchard()
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml index 4783387d6..3267dbdec 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Create.cshtml @@ -7,8 +7,7 @@ @@ -21,6 +20,6 @@
- +
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Edit.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Edit.cshtml index 8dc0d33f0..f12523648 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Edit.cshtml @@ -1,4 +1,5 @@ @model Orchard.Media.ViewModels.MediaFolderEditViewModel +@using Orchard.Media.Extensions; @using Orchard.Media.Helpers; @using Orchard.Media.Models; @{ Style.Require("MediaAdmin"); } @@ -24,7 +25,7 @@ - +
@@ -70,7 +71,7 @@ @mediaFile.User @mediaFile.LastUpdated @mediaFile.Type - @mediaFile.Size + @mediaFile.Size.ToFriendlySizeString() } @@ -87,7 +88,7 @@ @mediaFolder.User @mediaFolder.LastUpdated @T("Folder") - @mediaFolder.Size + @mediaFolder.Size.ToFriendlySizeString() } diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml index 6f1ac4f0d..311ccac8d 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditMedia.cshtml @@ -1,4 +1,5 @@ @model Orchard.Media.ViewModels.MediaItemEditViewModel +@using Orchard.Media.Extensions; @using Orchard.Media.Helpers; @using Orchard.Media.Models; @{ Style.Require("MediaAdmin"); } @@ -19,20 +20,20 @@ @Html.ValidationSummary()
- @Model.Caption +
@* todo: make these real (including markup) *@
@* *@ - +
- + @T("Copy this html to add this image to your site.")
@@ -42,9 +43,6 @@
- - - @T("This will be used for the image alt tag.") @@ -52,13 +50,13 @@
- +
@*

@T("Preview")

-
@Model.Caption
+
    @// todo: make these real (including markup)
  • @@ -66,7 +64,7 @@
  • - ", ResolveUrl("~/Media/" + Model.RelativePath + "/" + Model.Name), 500, 375, Model.Caption)" /> + ", ResolveUrl("~/Media/" + Model.RelativePath + "/" + Model.Name), 500, 375)" /> @T("Copy this html to add this image to your site.")

diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditProperties.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditProperties.cshtml index 2e7863f4c..ffb1697a1 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditProperties.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/EditProperties.cshtml @@ -22,7 +22,7 @@
- - + +
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Index.cshtml index 1c8f96a7b..564bd58ff 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Admin/Index.cshtml @@ -1,4 +1,5 @@ @model Orchard.Media.ViewModels.MediaFolderIndexViewModel +@using Orchard.Media.Extensions;

@Html.TitleForPage(T("Manage Media Folders").ToString())

@Html.ValidationSummary() @@ -8,7 +9,7 @@ - +
@Html.ActionLink(T("Add a folder").ToString(), "Create", new { }, new { @class = "button primaryAction" })
@@ -44,7 +45,7 @@ @mediaFolder.User @mediaFolder.LastUpdated @T("Folder") - @mediaFolder.Size + @mediaFolder.Size.ToFriendlySizeString() } diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/EditorTemplates/Parts/Media.MediaSettings.cshtml b/src/Orchard.Web/Modules/Orchard.Media/Views/EditorTemplates/Parts/Media.MediaSettings.cshtml new file mode 100644 index 000000000..5cc0a1d31 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/EditorTemplates/Parts/Media.MediaSettings.cshtml @@ -0,0 +1,9 @@ +@model Orchard.Media.Models.MediaSettingsPartRecord + +
+ @T("Media Settings") +
+ @Html.LabelFor(m => m.UploadAllowedFileTypeWhitelist, T("Upload allowed file types (list of extensions separated by spaces)")) + @Html.TextBoxFor(m => m.UploadAllowedFileTypeWhitelist, new { @class = "textMedium" }) +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Media/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Media/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Modules/Orchard.Media/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Media/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs index 867082e3f..99808b43b 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs @@ -2,7 +2,11 @@ using System.Linq; using System.Web.Mvc; using Orchard.Data.Migration; +using Orchard.Environment.Descriptor.Models; +using Orchard.Environment.Extensions; +using Orchard.Environment.Features; using Orchard.Localization; +using Orchard.Modules.Services; using Orchard.Modules.ViewModels; using Orchard.Packaging.Services; using Orchard.Reports.Services; @@ -14,18 +18,27 @@ namespace Orchard.Modules.Controllers { private readonly IDataMigrationManager _dataMigrationManager; private readonly IPackageManager _packageManager; private readonly IReportsCoordinator _reportsCoordinator; + private readonly IExtensionManager _extensionManager; + private readonly IFeatureManager _featureManager; + private readonly ShellDescriptor _shellDescriptor; public AdminController(IOrchardServices services, IModuleService moduleService, IDataMigrationManager dataMigrationManager, IPackageManager packageManager, - IReportsCoordinator reportsCoordinator) { + IReportsCoordinator reportsCoordinator, + IExtensionManager extensionManager, + IFeatureManager featureManager, + ShellDescriptor shellDescriptor) { Services = services; _moduleService = moduleService; _dataMigrationManager = dataMigrationManager; _packageManager = packageManager; _reportsCoordinator = reportsCoordinator; + _extensionManager = extensionManager; + _featureManager = featureManager; + _shellDescriptor = shellDescriptor; T = NullLocalizer.Instance; } @@ -37,7 +50,7 @@ namespace Orchard.Modules.Controllers { if (!Services.Authorizer.Authorize(Permissions.ManageModules, T("Not allowed to manage modules"))) return new HttpUnauthorizedResult(); - var modules = _moduleService.GetInstalledModules().ToList(); + var modules = _extensionManager.AvailableExtensions().Where(x => x.ExtensionType == "Module"); return View(new ModulesIndexViewModel { Modules = modules }); } @@ -83,10 +96,16 @@ namespace Orchard.Modules.Controllers { if (!Services.Authorizer.Authorize(Permissions.ManageFeatures, T("Not allowed to manage features"))) return new HttpUnauthorizedResult(); - var features = _moduleService.GetAvailableFeatures().Where(f => !f.Descriptor.Extension.ExtensionType.Equals("Theme", StringComparison.OrdinalIgnoreCase)).ToList(); var featuresThatNeedUpdate = _dataMigrationManager.GetFeaturesThatNeedUpdate(); - return View(new FeaturesViewModel { Features = features, FeaturesThatNeedUpdate = featuresThatNeedUpdate }); + var features = _featureManager.GetAvailableFeatures() + .Where(f => !f.Extension.ExtensionType.Equals("Theme", StringComparison.OrdinalIgnoreCase)) + .Select(f=>new ModuleFeature{Descriptor=f, + IsEnabled=_shellDescriptor.Features.Any(sf=>sf.Name==f.Name), + NeedsUpdate=featuresThatNeedUpdate.Contains(f.Name)}) + .ToList(); + + return View(new FeaturesViewModel { Features = features }); } [HttpPost] diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Models/Module.cs b/src/Orchard.Web/Modules/Orchard.Modules/Models/Module.cs deleted file mode 100644 index 0fc26089a..000000000 --- a/src/Orchard.Web/Modules/Orchard.Modules/Models/Module.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using Orchard.Environment.Extensions.Models; - -namespace Orchard.Modules.Models { - public class Module : IModule { - public string ModuleName { get; set; } - public string DisplayName { get; set; } - public string Description { get; set; } - public string Version { get; set; } - public string Author { get; set; } - public string HomePage { get; set; } - public string Tags { get; set; } - public IEnumerable Features { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj b/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj index e256af8af..96d456637 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj +++ b/src/Orchard.Web/Modules/Orchard.Modules/Orchard.Modules.csproj @@ -75,9 +75,8 @@ - + - @@ -88,7 +87,6 @@ - @@ -107,7 +105,16 @@ - + + + Designer + + + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Modules/styles/admin.css b/src/Orchard.Web/Modules/Orchard.Modules/styles/admin.css index 9500ca651..da9f10cdf 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.Modules/styles/admin.css @@ -14,9 +14,6 @@ } .features.summary-view .feature { border:1px solid #EAEAEA; - box-shadow: 0px 1px 2px #d6d6d6; - -moz-box-shadow: 0px 1px 2px #d6d6d6; - -webkit-box-shadow: 0px 1px 2px #d6d6d6; display:block; float:left; height:6em; @@ -93,10 +90,6 @@ .features.detail-view .description::before { content:" - "; } -.features .dependencies li, -.features .actions { - font-size:1.4em; -} .features .dependencies { font-size:.9em; margin:.44em 0 0; diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Content/Web.config b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Content/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Content/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Orchard.MultiTenancy.csproj b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Orchard.MultiTenancy.csproj index 016579f15..76aeae4ed 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Orchard.MultiTenancy.csproj +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Orchard.MultiTenancy.csproj @@ -91,7 +91,6 @@ - @@ -101,6 +100,16 @@ False + + + Designer + + + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Add.cshtml b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Add.cshtml index 3bc738332..30e4f1711 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Add.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Add.cshtml @@ -41,6 +41,6 @@
- +
} diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Edit.cshtml b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Edit.cshtml index 0aecbcc75..d1e96d65a 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Admin/Edit.cshtml @@ -43,6 +43,6 @@
- +
} diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Web.config b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Web.config index bf2230060..dd900f1a0 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj b/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj index ef1c9d653..8b9868e5c 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj @@ -108,9 +108,7 @@ - - @@ -119,10 +117,22 @@ - + - + + Designer + + + + + Designer + + + + + Designer + diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Properties/AssemblyInfo.cs index e24e79e36..dd435eda1 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -33,3 +33,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Scripts/Web.config b/src/Orchard.Web/Modules/Orchard.Packaging/Scripts/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Scripts/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.Packaging/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/AddSource.cshtml b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/AddSource.cshtml index 66af2d7ec..46d6b9f16 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/AddSource.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/AddSource.cshtml @@ -9,6 +9,6 @@
- +
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Harvest.cshtml b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Harvest.cshtml index 816701f86..7c875da58 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Harvest.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Gallery/Harvest.cshtml @@ -26,5 +26,7 @@ @Html.DropDownListFor(m => m.FeedUrl, new[]{new SelectListItem{Text=T("Download").ToString(),Value="Download"}}.Concat( Model.Sources.Select(x => new SelectListItem { Text = T("Push to {0}", x.FeedUrl).ToString(), Value = x.FeedUrl }))) @Html.ValidationMessageFor(m=>m.FeedUrl) - +
+ +
} diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Web.config index 3e2ccce91..271dd8ba1 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Views/Web.config @@ -3,7 +3,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Drivers/PublishLaterPartDriver.cs b/src/Orchard.Web/Modules/Orchard.PublishLater/Drivers/PublishLaterPartDriver.cs index a8ba7544a..5724829e3 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Drivers/PublishLaterPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Drivers/PublishLaterPartDriver.cs @@ -7,7 +7,6 @@ using Orchard.PublishLater.Services; using Orchard.PublishLater.ViewModels; using Orchard.Localization; using System.Globalization; -using Orchard.Core.Localization.Services; namespace Orchard.PublishLater.Drivers { public class PublishLaterPartDriver : ContentPartDriver { @@ -49,8 +48,8 @@ namespace Orchard.PublishLater.Drivers { // date and time are formatted using the same patterns as DateTimePicker is, preventing other cultures issues var model = new PublishLaterViewModel(part) { ScheduledPublishUtc = part.ScheduledPublishUtc.Value, - ScheduledPublishDate = part.ScheduledPublishUtc.Value.HasValue ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture) : String.Empty, - ScheduledPublishTime = part.ScheduledPublishUtc.Value.HasValue ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture) : String.Empty + ScheduledPublishDate = part.ScheduledPublishUtc.Value.HasValue && !part.IsPublished() ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture) : String.Empty, + ScheduledPublishTime = part.ScheduledPublishUtc.Value.HasValue && !part.IsPublished() ? part.ScheduledPublishUtc.Value.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture) : String.Empty }; return ContentShape("Parts_PublishLater_Edit", @@ -60,27 +59,24 @@ namespace Orchard.PublishLater.Drivers { var model = new PublishLaterViewModel(part); updater.TryUpdateModel(model, Prefix, null, null); - switch (model.Command) { - case "PublishNow": - _commonService.Publish(model.ContentItem); - break; - case "PublishLater": - DateTime scheduled; - string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime); - - // use an english culture as it is the one used by jQuery.datepicker by default - if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) { - model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime(); - _publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value); - } - else { - updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime)); - } - break; - case "SaveDraft": - break; + if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) && !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) { + DateTime scheduled; + string parseDateTime = String.Concat(model.ScheduledPublishDate, " ", model.ScheduledPublishTime); + + // use an english culture as it is the one used by jQuery.datepicker by default + if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out scheduled)) { + model.ScheduledPublishUtc = part.ScheduledPublishUtc.Value = scheduled.ToUniversalTime(); + _publishLaterService.Publish(model.ContentItem, model.ScheduledPublishUtc.Value); + } + else { + updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime)); + } } + else if (!string.IsNullOrWhiteSpace(model.ScheduledPublishDate) || !string.IsNullOrWhiteSpace(model.ScheduledPublishTime)) { + updater.AddModelError(Prefix, T("Both the date and time need to be specified for when this is to be published. If you don't want to schedule publishing then clear both the date and time fields.")); + } + return ContentShape("Parts_PublishLater_Edit", () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); } diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj b/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj index 40a706eda..05e35b33d 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Orchard.PublishLater.csproj @@ -83,7 +83,11 @@ - + + + Designer + + {2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6} @@ -123,6 +127,11 @@ Designer
+ + + Designer + + - + diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/Orchard.PublishLater/Properties/AssemblyInfo.cs index 531664349..4f10fb324 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -32,3 +32,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/datetime.css b/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/datetime.css index 21684b460..af6b87158 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/datetime.css +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Styles/datetime.css @@ -7,8 +7,8 @@ html.dyn input.hinted { font-style:italic; } input#PublishLater_ScheduledPublishDate { - width:50%; + width:49%; } input#PublishLater_ScheduledPublishTime { - width:36%; + width:43%; } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/ViewModels/PublishLaterViewModel.cs b/src/Orchard.Web/Modules/Orchard.PublishLater/ViewModels/PublishLaterViewModel.cs index 3961d56c4..4c5392c16 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/ViewModels/PublishLaterViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/ViewModels/PublishLaterViewModel.cs @@ -11,7 +11,6 @@ namespace Orchard.PublishLater.ViewModels { _publishLaterPart = publishLaterPart; } - public string Command { get; set; } public ContentItem ContentItem { get { return _publishLaterPart.ContentItem; } } public bool IsPublished { diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/EditorTemplates/Parts/PublishLater.cshtml b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/EditorTemplates/Parts/PublishLater.cshtml index 5b7681ce3..d0678e18b 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/EditorTemplates/Parts/PublishLater.cshtml +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/EditorTemplates/Parts/PublishLater.cshtml @@ -4,48 +4,36 @@ Script.Require("jQueryUI_DatePicker"); Style.Require("PublishLater_DatePicker"); Style.Require("jQueryUtils_TimePicker"); - Style.Require("jQueryUI_DatePicker"); + Style.Require("jQueryUI_DatePicker"); } -
- @T("Publish Settings") -
- @Html.RadioButton("Command", "SaveDraft", Model.ContentItem.VersionRecord == null || !Model.ContentItem.VersionRecord.Published, new { id = ViewData.TemplateInfo.GetFullHtmlFieldId("Command_SaveDraft") }) - -
-
- @Html.RadioButton("Command", "PublishNow", Model.ContentItem.VersionRecord != null && Model.ContentItem.VersionRecord.Published, new { id = ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishNow") }) - -
-
- @Html.RadioButton("Command", "PublishLater", Model.ScheduledPublishUtc != null, new { id = ViewData.TemplateInfo.GetFullHtmlFieldId("Command_PublishLater") }) - -
-
- - @Html.EditorFor(m => m.ScheduledPublishDate) - - @Html.EditorFor(m => m.ScheduledPublishTime) -
+
+ @T("Publish") + + @Html.EditorFor(m => m.ScheduledPublishDate) + + @Html.EditorFor(m => m.ScheduledPublishTime)
@using(Script.Foot()) { diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Parts/PublishLater.Metadata.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Parts/PublishLater.Metadata.SummaryAdmin.cshtml index b3163f8d1..1eb13bfe2 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Parts/PublishLater.Metadata.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Parts/PublishLater.Metadata.SummaryAdmin.cshtml @@ -8,16 +8,16 @@
  • @* Published or not *@ @if (publishLaterPart.HasPublished()) { - @T( @T("Published") |  + @T( @T("Published") |  } else { - @T( @T("Not Published") |  + @T( @T("Not Published") |  }
  • @* Does the page have a draft *@ @if (publishLaterPart.HasDraft()) { - @T( @T("Draft") |  + @T( @T("Draft") |  } else { @T("No Draft") |  @@ -29,7 +29,7 @@ @T("Published: {0}", Display.DateTimeRelative(dateTimeUtc: versionPublishedUtc.Value)) } else { - @T( @T("Scheduled") + @T( @T("Scheduled") @Html.DateTime(((DateTime?)Model.ScheduledPublishUtc).Value.ToLocalTime(), T("M/d/yyyy h:mm tt")) } | 
  • } diff --git a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Web.config b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.PublishLater/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Roles/Controllers/AdminController.cs index e611021c6..198fa1eb2 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Controllers/AdminController.cs @@ -148,6 +148,11 @@ namespace Orchard.Roles.Controllers { [HttpPost, ActionName("Edit")] [FormValueRequired("submit.Delete")] public ActionResult EditDeletePOST(int id) { + return Delete(id, null); + } + + [HttpPost] + public ActionResult Delete(int id, string returnUrl) { if (!Services.Authorizer.Authorize(Permissions.ManageRoles, T("Not authorized to manage roles"))) return new HttpUnauthorizedResult(); @@ -155,6 +160,10 @@ namespace Orchard.Roles.Controllers { _roleService.DeleteRole(id); Services.Notifier.Information(T("Role was successfully deleted.")); + + if (!string.IsNullOrWhiteSpace(returnUrl)) + return Redirect(returnUrl); + return RedirectToAction("Index"); } catch (Exception exception) { Services.Notifier.Error(T("Editing Role failed: {0}", exception.Message)); diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj index 2391a5824..12638ae72 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj +++ b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj @@ -95,7 +95,6 @@ - @@ -112,6 +111,11 @@ + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Search/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Search/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Modules/Orchard.Search/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Search/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.Tags/Styles/admin.css new file mode 100644 index 000000000..edf2945a1 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Tags/Styles/admin.css @@ -0,0 +1,11 @@ +.orchard-tags #main .manage form { + margin:0; +} +.orchard-tags .manage fieldset { + display:inline; + margin:0; + padding:0; +} +.orchard-tags .manage label[for=TagName] { + display:none; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminSearchViewModel.cs b/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminSearchViewModel.cs deleted file mode 100644 index bec3abf89..000000000 --- a/src/Orchard.Web/Modules/Orchard.Tags/ViewModels/TagsAdminSearchViewModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using Orchard.ContentManagement; - -namespace Orchard.Tags.ViewModels { - public class TagsAdminSearchViewModel { - public string TagName { get; set; } - public IEnumerable Contents { get; set; } - } -} diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Create.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Create.cshtml deleted file mode 100644 index 4c02b8174..000000000 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Create.cshtml +++ /dev/null @@ -1,15 +0,0 @@ -@model Orchard.Tags.ViewModels.TagsAdminCreateViewModel - -

    @Html.TitleForPage(T("Add a Tag").ToString())

    -@using (Html.BeginFormAntiForgeryPost()) { - @Html.ValidationSummary() - -
    - @Html.LabelFor(m => m.TagName, T("Tag Name")) - @Html.TextBoxFor(m=>m.TagName, new { @class = "text" }) -
    - -
    - -
    - } diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Edit.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Edit.cshtml index f316cb394..1bcbe8588 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Edit.cshtml @@ -1,6 +1,8 @@ @model Orchard.Tags.ViewModels.TagsAdminEditViewModel +@using Orchard.ContentManagement; +@using Orchard.Utility.Extensions; -

    @Html.TitleForPage(T("Edit a Tag").ToString())

    +

    @Html.TitleForPage(T("Manage tag: {0}", Model.TagName).ToString())

    @using (Html.BeginFormAntiForgeryPost()) { @Html.ValidationSummary()
    @@ -10,6 +12,30 @@
    - +
    - } +} +

    @T("Content items tagged with {0}", Model.TagName)

    +@if (View.ContentItems == null) { +

    @T("There is nothing tagged with {0}", Model.TagName)

    +} +else { + + + + + + + + + + + + @foreach (IContent content in View.ContentItems) { + + + + + } +
    @T("Content Type")@T("Name")
    @content.ContentItem.ContentType.CamelFriendly()@Html.ItemDisplayLink(content.ContentItem)
    +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Index.cshtml index d3d0b3b4c..deb569a1c 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Index.cshtml @@ -1,21 +1,25 @@ @model Orchard.Tags.ViewModels.TagsAdminIndexViewModel - @using Orchard.Tags.ViewModels; +@using Orchard.Utility.Extensions; +@{ + Script.Require("ShapesBase"); + Style.Require("TagsAdmin"); +}

    @Html.TitleForPage(T("Manage Tags").ToString())

    - - @Html.ValidationSummary() - +@Html.ValidationSummary() +
    + @Display.EditorTemplate(TemplateName: "Parts/CreateTag", Model: View.CreateTag != null ? View.CreateTag : new TagsAdminCreateViewModel()) +
    +@using(Html.BeginFormAntiForgeryPost()) {
    - +
    - -
    @Html.ActionLink(T("Add a tag").ToString(), "Create", new { }, new { @class = "button primaryAction" })
    @@ -36,13 +40,15 @@ tagIndex = tagIndex + 1; }
    - @Html.ActionLink(Html.Encode(tagEntry.Tag.TagName), "Search", new {id = tagEntry.Tag.Id}) + @Html.ActionLink(tagEntry.Tag.TagName, "Edit", new {id = tagEntry.Tag.Id}) - @Html.ActionLink(T("Edit").ToString(), "Edit", new {id = tagEntry.Tag.Id}) + @Html.ActionLink(T("Edit").ToString(), "Edit", new {id = tagEntry.Tag.Id}) @T(" | ") + @T("Remove")
    -
    \ No newline at end of file +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Search.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Search.cshtml deleted file mode 100644 index c90d2161b..000000000 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/Admin/Search.cshtml +++ /dev/null @@ -1,22 +0,0 @@ -@model Orchard.Tags.ViewModels.TagsAdminSearchViewModel -@using Orchard.ContentManagement; - -

@Html.TitleForPage(T("List of contents tagged with {0}", Model.TagName).ToString())

- - - - - - - - - - - - @foreach (var contentItem in Model.Contents) { - - - - - } -
@T("Name")@T("Link to the content item")
@Html.ItemDisplayText(contentItem)@Html.ItemDisplayLink(contentItem)
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/CreateTag.cshtml b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/CreateTag.cshtml new file mode 100644 index 000000000..0d7cbf8ff --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/EditorTemplates/Parts/CreateTag.cshtml @@ -0,0 +1,13 @@ +@model Orchard.Tags.ViewModels.TagsAdminCreateViewModel +@{ + Style.Require("TagsAdmin"); +} +@using (Html.BeginFormAntiForgeryPost()) { +
+ @Html.LabelFor(m => m.TagName, T("New Tag Name")) + @Html.TextBoxFor(m => m.TagName, new { @class = "text", placeholder = T("New Tag Name") }) +
+
+ +
+} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Tags/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Tags/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Themes/Controllers/AdminController.cs index 713383049..6bf7988ee 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/Controllers/AdminController.cs @@ -1,21 +1,29 @@ using System; +using System.Linq; using System.Reflection; using System.Web; using System.Web.Mvc; using Orchard.Data.Migration; using Orchard.DisplayManagement; +using Orchard.Environment.Descriptor.Models; +using Orchard.Environment.Extensions; +using Orchard.Environment.Features; using Orchard.Localization; using Orchard.Reports.Services; using Orchard.Security; using Orchard.Themes.Preview; +using Orchard.Themes.Services; using Orchard.Themes.ViewModels; using Orchard.UI.Notify; namespace Orchard.Themes.Controllers { [ValidateInput(false)] public class AdminController : Controller { - private readonly IThemeService _themeService; + private readonly ISiteThemeService _siteThemeService; private readonly IPreviewTheme _previewTheme; + private readonly IExtensionManager _extensionManager; + private readonly ShellDescriptor _shellDescriptor; + private readonly IThemeService _themeService; private readonly IDataMigrationManager _dataMigrationManager; private readonly IReportsCoordinator _reportsCoordinator; @@ -23,27 +31,44 @@ namespace Orchard.Themes.Controllers { IDataMigrationManager dataMigraitonManager, IReportsCoordinator reportsCoordinator, IOrchardServices services, - IThemeService themeService, + IThemeManager themeManager, + IFeatureManager featureManager, + ISiteThemeService siteThemeService, IPreviewTheme previewTheme, IAuthorizer authorizer, - INotifier notifier) { + INotifier notifier, + IExtensionManager extensionManager, + ShellDescriptor shellDescriptor, + IThemeService themeService) { Services = services; _dataMigrationManager = dataMigraitonManager; _reportsCoordinator = reportsCoordinator; - _themeService = themeService; + _siteThemeService = siteThemeService; _previewTheme = previewTheme; + _extensionManager = extensionManager; + _shellDescriptor = shellDescriptor; + _themeService = themeService; T = NullLocalizer.Instance; } - public IOrchardServices Services{ get; set; } + public IOrchardServices Services { get; set; } public Localizer T { get; set; } public ActionResult Index() { try { - var themes = _themeService.GetInstalledThemes(); - var currentTheme = _themeService.GetSiteTheme(); + var currentTheme = _siteThemeService.GetSiteTheme(); var featuresThatNeedUpdate = _dataMigrationManager.GetFeaturesThatNeedUpdate(); - var model = new ThemesIndexViewModel { CurrentTheme = currentTheme, Themes = themes, FeaturesThatNeedUpdate = featuresThatNeedUpdate }; + + var themes = _extensionManager.AvailableExtensions() + .Where(d => d.ExtensionType == "Theme") + .Select(d => new ThemeEntry { + Descriptor = d, + NeedsUpdate = featuresThatNeedUpdate.Contains(d.Name), + Enabled = _shellDescriptor.Features.Any(sf => sf.Name == d.Name) + }) + .ToArray(); + + var model = new ThemesIndexViewModel { CurrentTheme = currentTheme, Themes = themes }; return View(model); } catch (Exception exception) { @@ -71,8 +96,8 @@ namespace Orchard.Themes.Controllers { try { if (!Services.Authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't preview the current theme"))) return new HttpUnauthorizedResult(); - _previewTheme.SetPreviewTheme(null); - _themeService.SetSiteTheme(themeName); + _previewTheme.SetPreviewTheme(null); + _siteThemeService.SetSiteTheme(themeName); } catch (Exception exception) { Services.Notifier.Error(T("Previewing theme failed: " + exception.Message)); @@ -98,7 +123,8 @@ namespace Orchard.Themes.Controllers { try { if (!Services.Authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't enable the theme"))) return new HttpUnauthorizedResult(); - _themeService.EnableTheme(themeName); + + _themeService.EnableThemeFeatures(themeName); } catch (Exception exception) { Services.Notifier.Error(T("Enabling theme failed: " + exception.Message)); @@ -111,7 +137,8 @@ namespace Orchard.Themes.Controllers { try { if (!Services.Authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't disable the current theme"))) return new HttpUnauthorizedResult(); - _themeService.DisableTheme(themeName); + + _themeService.DisableThemeFeatures(themeName); } catch (Exception exception) { Services.Notifier.Error(T("Disabling theme failed: " + exception.Message)); @@ -124,7 +151,9 @@ namespace Orchard.Themes.Controllers { try { if (!Services.Authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't set the current theme"))) return new HttpUnauthorizedResult(); - _themeService.SetSiteTheme(themeName); + + _themeService.EnableThemeFeatures(themeName); + _siteThemeService.SetSiteTheme(themeName); } catch (Exception exception) { Services.Notifier.Error(T("Activating theme failed: " + exception.Message)); @@ -132,41 +161,6 @@ namespace Orchard.Themes.Controllers { return RedirectToAction("Index"); } - public ActionResult Install() { - return View(); - } - - [HttpPost] - public ActionResult Install(FormCollection input) { - try { - if (!Services.Authorizer.Authorize(Permissions.ManageThemes, T("Couldn't install theme"))) - return new HttpUnauthorizedResult(); - foreach (string fileName in Request.Files) { - HttpPostedFileBase file = Request.Files[fileName]; - _themeService.InstallTheme(file); - } - return RedirectToAction("Index"); - } - catch (Exception exception) { - Services.Notifier.Error(T("Installing theme failed: " + exception.Message)); - return RedirectToAction("Index"); - } - } - - [HttpPost] - public ActionResult Uninstall(string themeName) { - try { - if (!Services.Authorizer.Authorize(Permissions.ManageThemes, T("Couldn't uninstall theme"))) - return new HttpUnauthorizedResult(); - _themeService.UninstallTheme(themeName); - return RedirectToAction("Index"); - } - catch (Exception exception) { - Services.Notifier.Error(T("Uninstalling theme failed: " + exception.Message)); - return RedirectToAction("Index"); - } - } - [HttpPost] public ActionResult Update(string themeName) { if (!Services.Authorizer.Authorize(Permissions.ManageThemes, T("Couldn't update theme"))) diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Models/Theme.cs b/src/Orchard.Web/Modules/Orchard.Themes/Models/Theme.cs deleted file mode 100644 index 92877e672..000000000 --- a/src/Orchard.Web/Modules/Orchard.Themes/Models/Theme.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Orchard.Themes.Models { - public class Theme : ITheme { - public bool Enabled { get; set; } - public string ThemeName { get; set; } - public string DisplayName { get; set; } - public string Description { get; set; } - public string Version { get; set; } - public string Author { get; set; } - public string HomePage { get; set; } - public string Tags { get; set; } - public string Zones { get; set; } - public string BaseTheme { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Orchard.Themes.csproj b/src/Orchard.Web/Modules/Orchard.Themes/Orchard.Themes.csproj index 676a70308..aa29f8ae9 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Orchard.Themes.csproj +++ b/src/Orchard.Web/Modules/Orchard.Themes/Orchard.Themes.csproj @@ -75,7 +75,6 @@ - @@ -86,6 +85,7 @@ + @@ -95,7 +95,6 @@ - @@ -109,6 +108,16 @@ + + + Designer + + + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.Themes/Styles/admin.css index 362db6edd..ef12b4820 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.Themes/Styles/admin.css @@ -10,12 +10,6 @@ zoom:1; *display: inline; } -.templates .inline button { - font-size:1.2em; -} -.templates .wasFormInlineLink { - font-size:1.4em; -} .templates p { overflow:hidden; } diff --git a/src/Orchard.Web/Modules/Orchard.Themes/ViewModels/ThemesIndexViewModel.cs b/src/Orchard.Web/Modules/Orchard.Themes/ViewModels/ThemesIndexViewModel.cs index c31cc5a98..10aba3a0f 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/ViewModels/ThemesIndexViewModel.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/ViewModels/ThemesIndexViewModel.cs @@ -1,9 +1,21 @@ using System.Collections.Generic; +using Orchard.Environment.Extensions.Models; namespace Orchard.Themes.ViewModels { - public class ThemesIndexViewModel { - public ITheme CurrentTheme { get; set; } - public IEnumerable Themes { get; set; } - public IEnumerable FeaturesThatNeedUpdate { get; set; } + public class ThemesIndexViewModel { + public ExtensionDescriptor CurrentTheme { get; set; } + public IEnumerable Themes { get; set; } + } + + public class ThemeEntry { + public ExtensionDescriptor Descriptor { get; set; } + public bool Enabled { get; set; } + public bool NeedsUpdate { get; set; } + + public string ThemeName { get { return Descriptor.Name; } } + public string DisplayName { get { return Descriptor.DisplayName; } } + public string ThemePath(string path) { + return Descriptor.Location + "/" + Descriptor.Name + path; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml index ce05c4e67..241155080 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml @@ -15,7 +15,7 @@

@T("Version:") @Model.CurrentTheme.Version
@Model.CurrentTheme.Description
- @Model.CurrentTheme.HomePage + @Model.CurrentTheme.WebSite

@Html.ActionLink(T("Install a new Theme").ToString(), "Install", null, new { @class = "button primaryAction" }) @@ -24,11 +24,11 @@

@T("Available Themes")

    @foreach (var theme in Model.Themes) { - if (Model.CurrentTheme == null || theme.ThemeName != Model.CurrentTheme.ThemeName) { + if (Model.CurrentTheme == null || theme.ThemeName != Model.CurrentTheme.Name) {
  • @theme.DisplayName

    - @Html.Image(Href(Html.ThemePath(theme, "/Theme.png")), Html.Encode(theme.DisplayName), null) + @Html.Image(Href(theme.ThemePath("/Theme.png")), Html.Encode(theme.DisplayName), null) @using (Html.BeginFormAntiForgeryPost(Url.Action(theme.Enabled ? "Disable" : "Enable"), FormMethod.Post, new { @class = "inline" })) { @Html.Hidden("themeName", theme.ThemeName) @@ -41,13 +41,13 @@ @Html.Hidden("themeName", theme.ThemeName) } -
    @T("By") @theme.Author
    +
    @T("By") @theme.Descriptor.Author

    - @T("Version:") @theme.Version
    - @theme.Description
    - @theme.HomePage + @T("Version:") @theme.Descriptor.Version
    + @theme.Descriptor.Description
    + @theme.Descriptor.WebSite

    - @if(Model.FeaturesThatNeedUpdate.Contains(theme.ThemeName)){ + @if(theme.NeedsUpdate){ using (Html.BeginFormAntiForgeryPost(Url.Action("Update"), FormMethod.Post, new { @class = "inline link" })) { @Html.Hidden("themeName", theme.ThemeName)
    diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Install.cshtml b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Install.cshtml index c67534362..038ea80e9 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Install.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Install.cshtml @@ -4,7 +4,7 @@

    - + @Html.AntiForgeryTokenOrchard()
    } diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Themes/Views/Web.config index bf2230060..dd900f1a0 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs index beb07096a..e3c9ad8ca 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs @@ -10,8 +10,6 @@ using Orchard.Security; using Orchard.Themes; using Orchard.Users.Services; using Orchard.Users.ViewModels; -using Orchard.Settings; -using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.Users.Models; @@ -21,21 +19,23 @@ namespace Orchard.Users.Controllers { private readonly IAuthenticationService _authenticationService; private readonly IMembershipService _membershipService; private readonly IUserService _userService; + private readonly IOrchardServices _orchardServices; public AccountController( IAuthenticationService authenticationService, IMembershipService membershipService, - IUserService userService) { + IUserService userService, + IOrchardServices orchardServices) { _authenticationService = authenticationService; _membershipService = membershipService; _userService = userService; + _orchardServices = orchardServices; Logger = NullLogger.Instance; T = NullLocalizer.Instance; } public ILogger Logger { get; set; } public Localizer T { get; set; } - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } public ActionResult AccessDenied() { var returnUrl = Request.QueryString["ReturnUrl"]; @@ -93,7 +93,7 @@ namespace Orchard.Users.Controllers { public ActionResult Register() { // ensure users can register - var registrationSettings = CurrentSite.As(); + var registrationSettings = _orchardServices.WorkContext.CurrentSite.As(); if ( !registrationSettings.UsersCanRegister ) { return HttpNotFound(); } @@ -106,7 +106,7 @@ namespace Orchard.Users.Controllers { [HttpPost] public ActionResult Register(string userName, string email, string password, string confirmPassword) { // ensure users can register - var registrationSettings = CurrentSite.As(); + var registrationSettings = _orchardServices.WorkContext.CurrentSite.As(); if ( !registrationSettings.UsersCanRegister ) { return HttpNotFound(); } @@ -125,6 +125,10 @@ namespace Orchard.Users.Controllers { return RedirectToAction("ChallengeEmailSent"); } + if (user.As().RegistrationStatus == UserStatus.Pending) { + return RedirectToAction("RegistrationPending"); + } + _authenticationService.SignIn(user, false /* createPersistentCookie */); return Redirect("~/"); } @@ -174,6 +178,10 @@ namespace Orchard.Users.Controllers { } } + public ActionResult RegistrationPending() { + return View(); + } + public ActionResult ChangePasswordSuccess() { return View(); } diff --git a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AdminController.cs index d82a58a93..b7b0e3e55 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Users/Controllers/AdminController.cs @@ -1,11 +1,9 @@ using System.Linq; using System.Web.Mvc; -using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.DisplayManagement; using Orchard.Localization; using Orchard.Security; -using Orchard.Settings; using Orchard.UI.Notify; using Orchard.Users.Models; using Orchard.Users.Services; @@ -33,7 +31,6 @@ namespace Orchard.Users.Controllers { dynamic Shape { get; set; } public IOrchardServices Services { get; set; } public Localizer T { get; set; } - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } public ActionResult Index() { if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to list users"))) @@ -58,46 +55,52 @@ namespace Orchard.Users.Controllers { return new HttpUnauthorizedResult(); var user = Services.ContentManager.New("User"); - var model = new UserCreateViewModel { - User = Services.ContentManager.BuildEditor(user) - }; + var editor = Shape.EditorTemplate(TemplateName: "Parts/User.Create", Model: new UserCreateViewModel(), Prefix: null); + editor.Metadata.Position = "2"; + var model = Services.ContentManager.BuildEditor(user); + model.Content.Add(editor); + return View(model); } [HttpPost, ActionName("Create")] - public ActionResult CreatePOST(UserCreateViewModel model) { + public ActionResult CreatePOST(UserCreateViewModel createModel) { if (!Services.Authorizer.Authorize(Permissions.ManageUsers, T("Not authorized to manage users"))) return new HttpUnauthorizedResult(); - var user = Services.ContentManager.New("User"); - model.User = Services.ContentManager.UpdateEditor(user, this); - if (!ModelState.IsValid) { - Services.TransactionManager.Cancel(); - return View(model); + if (!string.IsNullOrEmpty(createModel.UserName)) { + string userExistsMessage = _userService.VerifyUserUnicity(createModel.UserName, createModel.Email); + if (userExistsMessage != null) { + AddModelError("NotUniqueUserName", T(userExistsMessage)); + } } - string userExistsMessage = _userService.VerifyUserUnicity(model.UserName, model.Email); - if (userExistsMessage != null) { - AddModelError("NotUniqueUserName", T(userExistsMessage)); - } - - if (model.Password != model.ConfirmPassword) { + if (createModel.Password != createModel.ConfirmPassword) { AddModelError("ConfirmPassword", T("Password confirmation must match")); } - user = _membershipService.CreateUser(new CreateUserParams( - model.UserName, - model.Password, - model.Email, - null, null, true)); + var user = Services.ContentManager.New("User"); + if (ModelState.IsValid) { + user = _membershipService.CreateUser(new CreateUserParams( + createModel.UserName, + createModel.Password, + createModel.Email, + null, null, true)); + } - model.User = Services.ContentManager.UpdateEditor(user, this); + var model = Services.ContentManager.UpdateEditor(user, this); - if (ModelState.IsValid == false) { + if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); + + var editor = Shape.EditorTemplate(TemplateName: "Parts/User.Create", Model: createModel, Prefix: null); + editor.Metadata.Position = "2"; + model.Content.Add(editor); + return View(model); } + Services.Notifier.Information(T("User created")); return RedirectToAction("edit", new { user.Id }); } @@ -106,10 +109,12 @@ namespace Orchard.Users.Controllers { return new HttpUnauthorizedResult(); var user = Services.ContentManager.Get(id); + var editor = Shape.EditorTemplate(TemplateName: "Parts/User.Edit", Model: new UserEditViewModel {User = user}, Prefix: null); + editor.Metadata.Position = "2"; + var model = Services.ContentManager.BuildEditor(user); + model.Content.Add(editor); - return View(new UserEditViewModel { - User = Services.ContentManager.BuildEditor(user) - }); + return View(model); } [HttpPost, ActionName("Edit")] @@ -118,26 +123,27 @@ namespace Orchard.Users.Controllers { return new HttpUnauthorizedResult(); var user = Services.ContentManager.Get(id); - var model = new UserEditViewModel { - User = Services.ContentManager.UpdateEditor(user, this) - }; + var model = Services.ContentManager.UpdateEditor(user, this); - TryUpdateModel(model); + var editModel = new UserEditViewModel {User = user}; + TryUpdateModel(editModel); - if (!ModelState.IsValid) { - Services.TransactionManager.Cancel(); - return View(model); - } + if (ModelState.IsValid) { + ((IContent)model.ContentItem).As().NormalizedUserName = editModel.UserName.ToLower(); - model.User.As().NormalizedUserName = model.UserName.ToLower(); - - string userExistsMessage = _userService.VerifyUserUnicity(id, model.UserName, model.Email); - if (userExistsMessage != null) { - AddModelError("NotUniqueUserName", T(userExistsMessage)); + string userExistsMessage = _userService.VerifyUserUnicity(id, editModel.UserName, editModel.Email); + if (userExistsMessage != null) { + AddModelError("NotUniqueUserName", T(userExistsMessage)); + } } if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); + + var editor = Shape.EditorTemplate(TemplateName: "Parts/User.Edit", Model: editModel, Prefix: null); + editor.Metadata.Position = "2"; + model.Content.Add(editor); + return View(model); } @@ -192,7 +198,7 @@ namespace Orchard.Users.Controllers { var user = Services.ContentManager.Get(id); if ( user != null ) { - if ( CurrentSite.SuperUser.Equals(user.As().UserName) ) { + if (Services.WorkContext.CurrentSite.SuperUser.Equals(user.As().UserName) ) { Services.Notifier.Error(T("Super user can't be moderated")); } else { diff --git a/src/Orchard.Web/Modules/Orchard.Users/Orchard.Users.csproj b/src/Orchard.Web/Modules/Orchard.Users/Orchard.Users.csproj index e78ca1397..0e6484899 100644 --- a/src/Orchard.Web/Modules/Orchard.Users/Orchard.Users.csproj +++ b/src/Orchard.Web/Modules/Orchard.Users/Orchard.Users.csproj @@ -109,7 +109,6 @@ - @@ -123,6 +122,16 @@ Designer + + + Designer + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Widgets/Controllers/AdminController.cs index 83da257c0..835c371c5 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Controllers/AdminController.cs @@ -7,7 +7,6 @@ using Orchard.Core.Contents.Controllers; using Orchard.Localization; using Orchard.UI.Admin; using Orchard.UI.Notify; -using Orchard.UI.Widgets; using Orchard.Widgets.Models; using Orchard.Widgets.Services; using Orchard.Widgets.ViewModels; @@ -20,16 +19,13 @@ namespace Orchard.Widgets.Controllers { private const string NotAuthorizedManageWidgetsLabel = "Not authorized to manage widgets"; private readonly IWidgetsService _widgetsService; - private readonly IRuleManager _ruleManager; public AdminController( IOrchardServices services, - IWidgetsService widgetsService, - IRuleManager ruleManager) { + IWidgetsService widgetsService) { Services = services; _widgetsService = widgetsService; - _ruleManager = ruleManager; T = NullLocalizer.Instance; } @@ -179,8 +175,6 @@ namespace Orchard.Widgets.Controllers { var model = Services.ContentManager.UpdateEditor(layerPart, this); - ValidateLayer(layerPart); - if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); return View(model); @@ -227,8 +221,6 @@ namespace Orchard.Widgets.Controllers { var model = Services.ContentManager.UpdateEditor(layerPart, this); - ValidateLayer(layerPart); - if (!ModelState.IsValid) { Services.TransactionManager.Cancel(); return View(model); @@ -339,27 +331,6 @@ namespace Orchard.Widgets.Controllers { RedirectToAction("Index"); } - public bool ValidateLayer(LayerPart layer) { - if ( String.IsNullOrWhiteSpace(layer.LayerRule) ) { - layer.LayerRule = "true"; - } - - if(_widgetsService.GetLayers().Count(l => String.Equals(l.Name, layer.Name, StringComparison.InvariantCultureIgnoreCase)) > 1) { // the current layer counts for 1 - ModelState.AddModelError("Name", T("A Layer with the same name already exists").Text); - return false; - } - - try { - _ruleManager.Matches(layer.LayerRule); - } - catch ( Exception e ) { - ModelState.AddModelError("Description", T("The rule is not valid: {0}", e.Message).Text); - return false; - } - - return true; - } - bool IUpdateModel.TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) { return base.TryUpdateModel(model, prefix, includeProperties, excludeProperties); } diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Drivers/LayerPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Widgets/Drivers/LayerPartDriver.cs index a37cfd2f6..e4d3c7b5d 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Drivers/LayerPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Drivers/LayerPartDriver.cs @@ -1,12 +1,31 @@ -using JetBrains.Annotations; +using System; +using System.Linq; +using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; +using Orchard.Localization; +using Orchard.UI.Widgets; using Orchard.Widgets.Models; +using Orchard.Widgets.Services; namespace Orchard.Widgets.Drivers { [UsedImplicitly] public class LayerPartDriver : ContentPartDriver { + private readonly IRuleManager _ruleManager; + private readonly IWidgetsService _widgetsService; + + public LayerPartDriver( + IRuleManager ruleManager, + IWidgetsService widgetsService) { + + _ruleManager = ruleManager; + _widgetsService = widgetsService; + + T = NullLocalizer.Instance; + } + + public Localizer T { get; set; } protected override DriverResult Editor(LayerPart layerPart, dynamic shapeHelper) { return ContentShape("Parts_Widgets_LayerPart", @@ -14,7 +33,23 @@ namespace Orchard.Widgets.Drivers { } protected override DriverResult Editor(LayerPart layerPart, IUpdateModel updater, dynamic shapeHelper) { - updater.TryUpdateModel(layerPart, Prefix, null, null); + if(updater.TryUpdateModel(layerPart, Prefix, null, null)) { + if ( String.IsNullOrWhiteSpace(layerPart.LayerRule) ) { + layerPart.LayerRule = "true"; + } + + if ( _widgetsService.GetLayers().Any(l => String.Equals(l.Name, layerPart.Name, StringComparison.InvariantCultureIgnoreCase))) { + updater.AddModelError("Name", T("A Layer with the same name already exists")); + } + + try { + _ruleManager.Matches(layerPart.LayerRule); + } + catch ( Exception e ) { + updater.AddModelError("Description", T("The rule is not valid: {0}", e.Message)); + } + } + return Editor(layerPart, shapeHelper); } } diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Filters/WidgetFilter.cs b/src/Orchard.Web/Modules/Orchard.Widgets/Filters/WidgetFilter.cs index bc0e46f69..b971b1659 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Filters/WidgetFilter.cs +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Filters/WidgetFilter.cs @@ -47,9 +47,8 @@ namespace Orchard.Widgets.Filters { IEnumerable widgetParts = _contentManager.Query().List(); IEnumerable activeLayers = _contentManager.Query().List(); - List activeLayerIds = new List(); + var activeLayerIds = new List(); foreach (var activeLayer in activeLayers) { - var context = workContext.HttpContext; // ignore the rule if it fails to execute try { if (_ruleManager.Matches(activeLayer.Record.LayerRule)) { @@ -57,7 +56,7 @@ namespace Orchard.Widgets.Filters { } } catch(Exception e) { - Logger.Debug(e, T("An error occured during layer evaluation on: {0}", activeLayer.Name).Text); + Logger.Warning(e, T("An error occured during layer evaluation on: {0}", activeLayer.Name).Text); } } diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Orchard.Widgets.csproj b/src/Orchard.Web/Modules/Orchard.Widgets/Orchard.Widgets.csproj index ea6196de0..24e6924a6 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Orchard.Widgets.csproj +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Orchard.Widgets.csproj @@ -38,6 +38,10 @@ ..\..\..\..\lib\claysharp\ClaySharp.dll + + False + ..\..\..\..\lib\dlr\Microsoft.Scripting.dll + @@ -94,7 +98,6 @@ - @@ -127,6 +130,16 @@ + + + Designer + + + + + Designer + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Styles/admin.css b/src/Orchard.Web/Modules/Orchard.Widgets/Styles/admin.css index 2c44a98d0..14438b614 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Styles/admin.css +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Styles/admin.css @@ -27,7 +27,6 @@ h4.widgets-layer-header { .widgets-availableWidgets table.items th { background: #f1f1f1; - font-size:1.6em; padding:.5em 0 .3em .2em; } @@ -39,7 +38,6 @@ h4.widgets-layer-header { } .widgets-layerZones { - font-size: 1.4em; float: left; float: right; width: 60%; @@ -76,7 +74,6 @@ h4.widgets-layer-header { } .widgets-layers { - font-size: 1.4em; border:1px solid #ccc; border-right:none; } diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditLayer.cshtml b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditLayer.cshtml index 87aa30d15..d5292641b 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditLayer.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditLayer.cshtml @@ -4,6 +4,6 @@ @Display(Model)
    - +
    } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditWidget.cshtml b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditWidget.cshtml index 8d7f36a5c..a3b6aacf1 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditWidget.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Admin/EditWidget.cshtml @@ -4,6 +4,7 @@ @Display(Model)
    - + +
    } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Items/Widget.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Items/Widget.Edit.cshtml index 696503b21..ee08a573d 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Items/Widget.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Items/Widget.Edit.cshtml @@ -4,9 +4,5 @@
    @Display(Model.Sidebar) - @* todo: (heskew) remove when the CommonPart is adding the save button *@ -
    - -
    diff --git a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Web.config b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Web.config index d52f8e346..1f92a3531 100644 --- a/src/Orchard.Web/Modules/Orchard.Widgets/Views/Web.config +++ b/src/Orchard.Web/Modules/Orchard.Widgets/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Styles/Web.config b/src/Orchard.Web/Modules/Orchard.jQuery/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.jQuery/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/Orchard.jQuery/Web.config b/src/Orchard.Web/Modules/Orchard.jQuery/Web.config deleted file mode 100644 index cf1174676..000000000 --- a/src/Orchard.Web/Modules/Orchard.jQuery/Web.config +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Orchard.Web/Modules/TinyMce/Properties/AssemblyInfo.cs b/src/Orchard.Web/Modules/TinyMce/Properties/AssemblyInfo.cs index 78f8be6f3..081f3f42d 100644 --- a/src/Orchard.Web/Modules/TinyMce/Properties/AssemblyInfo.cs +++ b/src/Orchard.Web/Modules/TinyMce/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -32,3 +32,4 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard.Web/Modules/TinyMce/Scripts/Web.config b/src/Orchard.Web/Modules/TinyMce/Scripts/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Modules/TinyMce/Scripts/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj b/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj index 9e5c17b6d..77afab906 100644 --- a/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj +++ b/src/Orchard.Web/Modules/TinyMce/TinyMce.csproj @@ -157,7 +157,11 @@ - + + + + Designer + diff --git a/src/Orchard.Web/Modules/TinyMce/Views/Web.config b/src/Orchard.Web/Modules/TinyMce/Views/Web.config index 5c6614a80..37513c05c 100644 --- a/src/Orchard.Web/Modules/TinyMce/Views/Web.config +++ b/src/Orchard.Web/Modules/TinyMce/Views/Web.config @@ -2,8 +2,6 @@ - + + + + + + + + + + diff --git a/src/Orchard.Web/Themes/SafeMode/Styles/Web.config b/src/Orchard.Web/Themes/SafeMode/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Themes/SafeMode/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Themes/Secundus/Theme.png b/src/Orchard.Web/Themes/Secundus/Theme.png new file mode 100644 index 000000000..e1371de56 Binary files /dev/null and b/src/Orchard.Web/Themes/Secundus/Theme.png differ diff --git a/src/Orchard.Web/Themes/Secundus/Theme.txt b/src/Orchard.Web/Themes/Secundus/Theme.txt new file mode 100644 index 000000000..172eecbf1 --- /dev/null +++ b/src/Orchard.Web/Themes/Secundus/Theme.txt @@ -0,0 +1,8 @@ +Name: Secundus +Author: Lou +Description: desc +Version: 0.1 +Website: http://whereslou.com +Zones: Main, Sidebar +BaseTheme: Primus + diff --git a/src/Orchard.Web/Themes/TheAdmin/Scripts/Web.config b/src/Orchard.Web/Themes/TheAdmin/Scripts/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Themes/TheAdmin/Scripts/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/Web.config b/src/Orchard.Web/Themes/TheAdmin/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Themes/TheAdmin/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/images/orchardLogo.gif b/src/Orchard.Web/Themes/TheAdmin/Styles/images/orchardLogo.gif index 7496b50f6..ecfd428d6 100644 Binary files a/src/Orchard.Web/Themes/TheAdmin/Styles/images/orchardLogo.gif and b/src/Orchard.Web/Themes/TheAdmin/Styles/images/orchardLogo.gif differ diff --git a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css index 8ae765e65..50b36bcbe 100644 --- a/src/Orchard.Web/Themes/TheAdmin/Styles/site.css +++ b/src/Orchard.Web/Themes/TheAdmin/Styles/site.css @@ -1,70 +1,143 @@ -/* begin: reset - todo: (heskew) pare down and combine with existing selectors where appropriate */ -/* http://meyerweb.com/eric/tools/css/reset/ */ -/* v1.0 | 20080212 */ +/* +Theme: Theme Admin +Author: Orchard Team – http://www.orchardproject.net +Copyright: 2010, Orchard. All Rights Reserved +*/ + + +/* Color Palette +************************************************************** + +Background: +Borders: +Text: +Secondary Text: +Main Accent: +Links: +*/ + + + +/* Reset +***************************************************************/ + html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, -b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { - border:0; - font-size:100%; - margin:0; - padding:0; - vertical-align:baseline; -} -ol, ul { - list-style:none; -} -blockquote, q { - quotes:none; + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; } + +/* Remember focus styles! */ +:focus { outline: 0; } + +body { line-height: 1; color: black; background: white; } +ol, ul { list-style: none; } + +/* Tables still need 'cellspacing="0"' in the markup */ +table { border-collapse: separate; border-spacing: 0; } +caption, th, td { text-align: left; font-weight: normal; } + blockquote:before, blockquote:after, -q:before, q:after { - content:''; - content:none; -} -ins { - text-decoration:none; -} -del { - text-decoration:line-through; -} -table { - border-collapse:collapse; - border-spacing:0; -} +q:before, q:after { content: ""; } +blockquote, q { quotes: "" ""; } + +/* HTML 5 elements as block */ +header, footer, aside, nav, article { display: block; } /* end: reset */ -/* Base setup -----------------------------------------------------------*/ + +/* Clearing Floats +***************************************************************/ + +.group:after +{ + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + + +/* General +***************************************************************/ + +/* Default font settings. +The font-size 81.3% sets the base font to 13px + +Pixels EMs Percent Points +6px 0.462em 46.2% 5pt +7px 0.538em 53.8% 5pt +8px 0.615em 61.5% 6pt +9px 0.692em 69.2% 7pt +10px 0.769em 76.9% 8pt +11px 0.846em 84.6% 8pt +12px 0.923em 92.3% 9pt +13px 1em 100% 10pt +14px 1.077em 107.7% 11pt +15px 1.154em 115.4% 11pt +16px 1.231em 123.1% 12pt +17px 1.308em 130.8% 13pt +18px 1.385em 138.5% 14pt +19px 1.462em 146.2% 14pt +20px 1.538em 153.8% 15pt +21px 1.615em 161.5% 16pt +22px 1.692em 169.2% 17pt +23px 1.769em 176.9% 17pt +24px 1.846em 184.6% 18pt +*/ + html { background:#2d2f25; color:#333; } -body { - color:#333; - font-family:Segoe UI,Trebuchet,Arial,Sans-Serif; - font-size:62.5%; /* 10px */ - line-height:1.6em; - margin:0 auto 1em; - min-width:74em; /* 946px */ - padding:0; + +body { + font-size: 81.3%; + color: #333; + background: #fff; + font-family: Segoe UI,Trebuchet,Arial,Sans-Serif; + line-height:1.6em; + margin:0 auto 1em; + min-width:74em; /* 946px */ + padding:0; } -button { - font-family:Segoe UI,Trebuchet,Arial,Sans-Serif; + +/* Headings */ +h1,h2,h3,h4,h5,h6 { font-weight: normal;} + +h1 { font-size: 1.692em } +h2 { font-size: 1.538em; } +h3 { font-size: 1.231em; } +h4 { font-size: 1.154em; } +h5 { font-size: 1.077em; } +h6 { font-size: 1em; } + +h1, h2, h3, h4, h5, legend { + padding:.4em 0; + font-style: normal; + font-weight:normal; } -body#preview { - min-width:0; -} -#content { - background:#fcfcfc; + +h1 img, h2 img, h3 img, +h4 img, h5 img, h6 img { + margin: 0; } + /* Layout number of columns: 24; actual width: 946; column width: 26; gutter width:14 @@ -120,48 +193,14 @@ number of columns: 24; actual width: 946; column width: 26; gutter width:14 display:inline; float:left; width:15.401%; - border-right:1px solid #eaeaea; } .wrapper, .sections { overflow:hidden; } -.sections .primary { - display:inline; - float:left; - width:74.543%; -} -.sections .secondary { - display:inline; - float:left; - margin-left:1.71%; - width:23.629%; -} -/* Headings and defaults -----------------------------------------------------------*/ -h1, h2, h3, h4, h5, legend { - padding:.4em 0; - font-style: normal; - font-weight:normal; -} -h1 { font-size:2.6em; } /* 26px */ -h2 { font-size:2.1em; } /* 21px */ -h2 span { font-size:.57em; } /* 12px */ -h3 { font-size:1.8em; } /* 18px */ -h3 span { font-size:.667em; } /* 12px */ -h4 { font-size:1.6em; } /* 16px */ -h5 { font-size:1.4em; } /* 14px */ - -h6, p, dl, label, /*input, select,*/ .button, -.message, .validation-summary-errors, -table.items th, table.items td, table.items caption { font-size:1.4em; line-height:1.4em; } /* 14px */ -table.items p, table.items label, table.items input, table.items .button { font-size:1em; line-height:1em; } -p .button { font-size:inherit; } -.meta, .hint { font-size:1.2em; } /* 12px */ -form.link button { font-size:1.01em; } /* Links -----------------------------------------------------------*/ +***************************************************************/ a, a:link, a:visited, form.link button { color:#1e5d7d; @@ -179,7 +218,7 @@ form.link button:hover { } /* Header - Branding and Login -----------------------------------------------------------*/ +***************************************************************/ #header { background:#2d2f25 url(images/backgroundHeader.gif) no-repeat bottom right; height:50px; @@ -195,44 +234,37 @@ form.link button:hover { height:60px; margin:-11px 0 0 14px; text-indent:-9999px; - width:105px; -} -#header #app a { - background:url(images/orchardLogo.gif) no-repeat; - display:block; - height:60px; - margin:-11px 0 0 14px; - text-indent:-9999px; - width:35px; + width:40px; } #site { - font-size:2em; + font-size:1.385em; /*18px*/ } #site a, #site a:visited, #site a:active { color:#fff; float:left; - line-height:2.2em; - padding:0 0 0 6px; + line-height:2.6em; position:relative; } + #login { - font-size:1.5em; color:#fff; display:block; float:right; - margin:16px 20px 0 0; + margin:14px 20px 0 0; white-space:nowrap; } + #login a, #login a:link, #login a:visited { color:#fff; padding:0; } + #login a:hover, #login a:active, #login a:focus { color:#ffea9b; } /* Navigation -----------------------------------------------------------*/ +***************************************************************/ #navshortcut { height:0; overflow:hidden; @@ -254,7 +286,6 @@ form.link button:hover { #menu .menu-admin ul a, #menu .menu-admin ul a:link, #menu .menu-admin ul a:visited { color:#2d2f25; display:block; - font-size:1.4em; line-height:1.2em; padding:.4em 0 .4em 12px; text-decoration:none; @@ -264,7 +295,15 @@ form.link button:hover { color: #000; text-decoration:underline; } - +#menu .menu-admin li.section-dashboard h3 { + padding:.4em 0 0 .4em; + font-size:1.308em; +} +.section-new { + border-top:1px solid #d3d3d3; + border-bottom:1px solid #d3d3d3; + padding:12px 0; +} /* todo: make generic so all toggles can use this and clean up jQuery */ .expando-glyph-container { display:inline !important; @@ -316,7 +355,7 @@ form.link button:hover { } /* Content -----------------------------------------------------------*/ +***************************************************************/ #main h1 { margin:0 0 1em; } @@ -338,20 +377,16 @@ form.link button:hover { #main form.inline { margin:0; } -#main h1, #main h2 { - border-bottom:1px solid #eaeaea; -} #main ul h2 { border-bottom:0; margin:.2em 0; } #main ul h3 { - font-size:1.6em; margin:0 0 .2em; } /* Confirmations, Messages and the like -----------------------------------------------------------*/ +***************************************************************/ .message, .validation-summary-errors { margin:10px 0 4px 0; padding:4px; @@ -398,8 +433,15 @@ span.message { content:"DEBUG » "; } -/* Forms -----------------------------------------------------------*/ +/* Forms +***************************************************************/ + +form { margin: 0; padding: 0; } +legend { font-size: 1.231em; font-weight: normal; border:none; } +fieldset { padding:0em; margin: 0 0 0em 0; border: 0px solid #dbdbdb; } +label { font-weight:normal; display:block; padding: 0 0 0.3em 0; } +label.forcheckbox { margin:0 0 0 .4em; display:inline; } + form.inline, form.inline fieldset { /* todo: (heskew) need something other than .inline ... */ display:inline; } @@ -412,22 +454,10 @@ form.inline fieldset { margin:0 1.4em 0 0; padding-top:0; } -legend { - font-size:1.6em; - font-weight:bold; -} + legend span { font-weight:normal; } -label { - display:block; - color:#4c4c4c; - font-weight:bold; -} -label.forcheckbox { - display:inline; - line-height:1.8em; -} .bulk-actions label, .bulk-items h3, label.sub { display:inline; } @@ -487,40 +517,33 @@ textarea { display:block; margin:0; } -.secondary fieldset { - margin:.446% 0 .446% .446%; - padding:4px; - width:98.662%; -} -button, .button, .button:link, .button:visited { - background:#F5F5F5; - background: -webkit-gradient(linear, left top, left bottom, from(#F5F5F5), to(#cbcbcb)); - background:-moz-linear-gradient(top , #F5F5F5, #cbcbcb); - border:1px solid #999999; - color:#2D2F25; - cursor:pointer; - padding:0 0.8em 0.1em 0.8em; - text-align:center; - text-shadow: 0 1px 1px rgba(0,0,0,.2); - box-shadow: 0 4px 4px rgba(231,231,231,.2) inset; - -webkit-box-shadow: 0 4px 4px rgba(231,231,231,.2) inset; - -moz-box-shadow: 0 4px 4px rgba(231,231,231,.2) inset; - -} form.link button { background:inherit; border:0; padding:0; width:auto; margin:-2px -3px 0; - + + /*Remove CSS3 button properties*/ + filter:none; + background:none; + background:none; + box-shadow:none; + -webkit-box-shadow:none; + -moz-box-shadow:none; + border-radius:none; + -webkit-border-radius:none; + -moz-border-radius:none; } -.primaryAction, .primaryAction:link, .primaryAction:visited { +button.primaryAction, .button.primaryAction, .button.primaryAction:link, .button.primaryAction:visited { background:#4687ad; + border:1px solid #405f71; + color:#fff; + + /*CSS3 properties*/ + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#4687AD', endColorstr='#366581'); background: -webkit-gradient(linear, left top, left bottom, from(#4687AD), to(#366581)); background:-moz-linear-gradient(top , #4687AD, #366581); - border:1px solid #405f71; - color:#fff; } button.remove, .remove.button, .remove.button:link, .remove.button:visited { background-color:#DECCCA; @@ -528,20 +551,6 @@ button.remove, .remove.button, .remove.button:link, .remove.button:visited { border-color:#d6c9c7; color:#5c3732; } -button:hover, .button:hover, -button:active, .button:active, -button:focus, .button:focus { - border-color:#bb8b2d; - color:#fff; - text-decoration:none; - background: #ffac40; - background: -webkit-gradient(linear, left top, left bottom, from(#ffac40), to(#f06015)); - background: -moz-linear-gradient(top, #ffac40, #f9760d); - -} -button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner { - border-color:#8a8f7a; -} button.remove:hover, .remove.button:hover, button.remove:active, .remove.button:active, button.remove:focus, .remove.button:focus { @@ -555,6 +564,56 @@ button.remove:focus::-moz-focus-inner, .remove.button:focus::-moz-focus-inner { .delete.button { float:right; } +input[type="submit"], input[type="reset"], input[type="button"], button, .button, .button:link, .button:visited + { + font-size: 107.7%; /*14px*/ + color:#333; + background:#F5F5F5; + border:1px solid #999; + cursor:pointer; + padding: 0 12px 2px 12px; + text-align:center; + + /*CSS3 properties*/ + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f5f5f5', endColorstr='#cbcbcb'); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#cbcbcb)); + background: -moz-linear-gradient(top, #f5f5f5, #cbcbcb); + box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3); + -webkit-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3); + -moz-box-shadow: inset 0px 0px 1px rgba(255, 255, 255, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3); + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + } +input[type="submit"]:hover,input[type="reset"]:hover, input[type="button"]:hover, button:hover, .button:hover, .button.primaryAction:hover { + text-decoration:none; + background: #ffac40; + color:#fff; + border:1px solid #bb8b2d; + + /*CSS3 properties*/ + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffac40', endColorstr='#f9760d'); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#ffac40), to(#f9760d)); + background: -moz-linear-gradient(top, #ffac40, #f9760d); +} +input[type="submit"]:active, input[type="reset"]:active, input[type="button"]:active, button:active, .buton:active, .button.primaryAction:active { + text-decoration:none; + background: #62a9e2; + color:#fff; + border:1px solid #bb772d; + + /*CSS3 properties*/ + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fece3b', endColorstr='#fe6001'); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#fece3b), to(#fe6001)); + background: -moz-linear-gradient(top, #fece3b, #fe6001); + box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3); + -moz-box-shadow: inset 0px 0px 1px rgba(254, 225, 109, 1.0), 1px 1px 1px rgba(102, 102, 102, 0.3); + -webkit-box-shadow: inset 1px 1px 1px rgba(254, 225, 109, 0.6), 1px 1px 1px rgba(102, 102, 102, 0.1); +} +input[type="submit"]:focus::-moz-focus-inner, button:focus::-moz-focus-inner, .button:focus::-moz-focus-inner { + border: 1px dotted transparent; +} + .cancel { margin:0 0 0 .93em; } @@ -613,49 +672,6 @@ button.remove:focus::-moz-focus-inner, .remove.button:focus::-moz-focus-inner { } -/* Icon buttons -----------------------------------------------------------*/ -.ibutton, .ibutton:link, .ibutton:visited, -button.ibutton, button.ibutton:hover, button.ibutton:focus, button.ibutton:active { - background:url(images/icons.png) 0 -20px; - border:0; - display:inline; - float:left; - height:17px; - overflow:hidden; - padding:0 0 0 17px; - width:0; -} -button.ibutton { - text-indent:-9999em; -} -.ibutton:hover, .ibutton:active, .ibutton:focus { background-position:0 0; } -.ibutton.remove, -.ibutton.remove:link, -.ibutton.remove:visited { background-position:-20px -20px; } -.ibutton.remove:hover, .ibutton.remove:active, .ibutton.remove:focus { background-position:-20px 0; } -.ibutton.view, -.ibutton.view:link, -.ibutton.view:visited { background-position:-40px -20px; } -.ibutton.view:hover, .ibutton.view:active, .ibutton.view:focus { background-position:-40px 0; } -.ibutton.add.page, -.ibutton.add.page:link, -.ibutton.add.page:visited { background-position:-60px -20px; } -.ibutton.add.page:hover, .ibutton.add.page:active, .ibutton.add.page:focus { background-position:-60px 0; } -.ibutton.edit, -.ibutton.edit:link, -.ibutton.edit:visited { background-position:-80px -20px; } -.ibutton.edit:hover, .ibutton.edit:active, .ibutton.edit:focus { background-position:-80px 0; } -.ibutton.publish, -.ibutton.publish:link, -.ibutton.publish:visited { background-position:-100px -20px; } -.ibutton.publish:hover, .ibutton.publish:active, .ibutton.publish:focus { background-position:-100px 0; } -.ibutton.blog, -.ibutton.blog:link, -.ibutton.blog:visited { background-position:-120px -20px; } -.ibutton.blog:hover, .ibutton.blog:active, .ibutton.blog:focus { background-position:-120px 0; } - - /* (Items) Tables ----------------------------------------------------------*/ table.items { @@ -704,17 +720,6 @@ table.items th, table.items td { padding:8px 12px; vertical-align:middle; } -table.items td -{ - vertical-align:top; -} -/* todo: Find a better way to do this. These are a fix for buttons and label fonts becomming too large in a table.*/ -table label { - font-size:1em; -} -table .button { - font-size:1em; -} /* Content item lists ----------------------------------------------------------*/ @@ -783,16 +788,13 @@ table .button { .contentItems .properties li { border:0; float:left; - font-size:1.4em; padding:0 0 .1em 0; } .contentItems .properties .icon { margin:0 .2em -.2em; } .contentItems .related { - text-align:right; - font-size:1.4em; } .contentItems .commentcount { line-height:2em; @@ -832,15 +834,58 @@ table .button { white-space:nowrap; } /* Settings */ -.settings fieldset { +.orchard-media fieldset div, .settings fieldset div, .settings .button { margin:.5em 0; - padding:1em; -} -.orchard-media fieldset div, .settings fieldset div, .orchard-media .button, .settings .button { - margin:1em 0 .5em 1em; } .settings legend { - margin:0 0 -.4em 0; + margin:0 0 -.4em; +} +/* Core Contents and Orchard.PublishLater */ + +.orchard-blogs .edit-item-sidebar, .contents .edit-item-sidebar +{ + border:1px solid #d3d3d3; + padding:6px; + + /*CSS3 properties*/ + filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f7f7f7', endColorstr='#f5f5f5'); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#f7f7f7), to(#f5f5f5)); + background: -moz-linear-gradient(top, #f7f7f7, #f5f5f5); + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} + +.edit-item-sidebar fieldset { + margin:0; + padding:0; +} + +fieldset.publish-button { + clear:none; + float:left; + margin: 0 12px; + padding: 0 12px; + border-left:1px solid #ccc; +} +fieldset.save-button { + clear:none; + float:left; + padding-right:0; + width:auto; +} +fieldset.publish-later-datetime { + clear:none; + float:left; + margin: 0 6px; +} +fieldset.publish-later-datetime legend { + display:none; +} +fieldset.publish-later-datetime input { + padding:1px; + text-align:center; + color:#666; } /* Fields @@ -857,4 +902,13 @@ table .button { /* todo: needed? */ .clearBoth { clear:both; +} +.placeholderd { + color:#ccc; + font-style:italic; +} +#orchard-version { + color:#FCFCFC; + float:right; + padding:.7em 1.4em; } \ No newline at end of file diff --git a/src/Orchard.Web/Themes/TheAdmin/Views/Layout.cshtml b/src/Orchard.Web/Themes/TheAdmin/Views/Layout.cshtml index 53578ce4e..d4afca4ed 100644 --- a/src/Orchard.Web/Themes/TheAdmin/Views/Layout.cshtml +++ b/src/Orchard.Web/Themes/TheAdmin/Views/Layout.cshtml @@ -17,12 +17,8 @@ // experimentation var thisUser = Html.Resolve().GetAuthenticatedUser(); - Model.Header.Add(Display.User(CurrentUser: thisUser), "after"); - - // these are just hacked together to fire existing partials... can change - - //Model.Zones.AddRenderPartial("header", "Header", Model); - //Model.Zones.AddRenderPartial("header:after", "User", Model); // todo: (heskew) should be a user display or widget + Model.Header.Add(Display.User(CurrentUser: thisUser)); + Model.Footer.Add(Display.OrchardVersion()); } @@ -39,4 +35,5 @@ @Display(Model.Navigation) \ No newline at end of file + @Display(Model.Footer) + \ No newline at end of file diff --git a/src/Orchard.Web/Themes/TheAdmin/Views/OrchardVersion.cshtml b/src/Orchard.Web/Themes/TheAdmin/Views/OrchardVersion.cshtml new file mode 100644 index 000000000..9b04becea --- /dev/null +++ b/src/Orchard.Web/Themes/TheAdmin/Views/OrchardVersion.cshtml @@ -0,0 +1,4 @@ +@{ + var version = new System.Reflection.AssemblyName(typeof(Orchard.ContentManagement.ContentItem).Assembly.FullName).Version.ToString(); +} +
    @T("Orchard v.{0}", version)
    \ No newline at end of file diff --git a/src/Orchard.Web/Themes/TheThemeMachine/Styles/Web.config b/src/Orchard.Web/Themes/TheThemeMachine/Styles/Web.config new file mode 100644 index 000000000..b4210f3e0 --- /dev/null +++ b/src/Orchard.Web/Themes/TheThemeMachine/Styles/Web.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/src/Orchard.Web/Themes/Themes.csproj b/src/Orchard.Web/Themes/Themes.csproj index 7d12ed2ce..c7adcbe36 100644 --- a/src/Orchard.Web/Themes/Themes.csproj +++ b/src/Orchard.Web/Themes/Themes.csproj @@ -49,6 +49,10 @@ + + + + @@ -58,9 +62,17 @@ - + Designer + + Designer + + + + + Designer + @@ -94,7 +106,19 @@ - + + Designer + + + + + Designer + + + + + Designer + diff --git a/src/Orchard.Web/Themes/Web.config b/src/Orchard.Web/Themes/Web.config index ae3d47d77..a2d69a7b9 100644 --- a/src/Orchard.Web/Themes/Web.config +++ b/src/Orchard.Web/Themes/Web.config @@ -2,13 +2,9 @@ - - - - - + + - + diff --git a/src/Orchard.Web/Web.config b/src/Orchard.Web/Web.config index be12b290a..05dce1250 100644 --- a/src/Orchard.Web/Web.config +++ b/src/Orchard.Web/Web.config @@ -66,6 +66,26 @@ + + + + + + + + + + + + + + + + + + + + - - + + + + + - - - - - - - - - - + + + + + + + + diff --git a/src/Orchard.sln b/src/Orchard.sln index 2f7139dc3..839c5af7c 100644 --- a/src/Orchard.sln +++ b/src/Orchard.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}" @@ -93,7 +92,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Themes", "Orchard.Web\Theme EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.PublishLater", "Orchard.Web\Modules\Orchard.PublishLater\Orchard.PublishLater.csproj", "{C889167C-E52C-4A65-A419-224B3D1B957D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.ContentQueries", "Orchard.Web\Modules\Orchard.ContentQueries\Orchard.ContentQueries.csproj", "{848126A0-9C88-415A-868F-F5F03449D0B6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Lists", "Orchard.Web\Modules\Orchard.Lists\Orchard.Lists.csproj", "{137906EA-15FE-4AD8-A6A0-27528F0477D6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -494,16 +493,13 @@ Global {C889167C-E52C-4A65-A419-224B3D1B957D}.FxCop|Any CPU.Build.0 = Release|Any CPU {C889167C-E52C-4A65-A419-224B3D1B957D}.Release|Any CPU.ActiveCfg = Release|Any CPU {C889167C-E52C-4A65-A419-224B3D1B957D}.Release|Any CPU.Build.0 = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Coverage|Any CPU.ActiveCfg = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Coverage|Any CPU.Build.0 = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.FxCop|Any CPU.ActiveCfg = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.FxCop|Any CPU.Build.0 = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {848126A0-9C88-415A-868F-F5F03449D0B6}.Release|Any CPU.Build.0 = Release|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.Coverage|Any CPU.ActiveCfg = Release|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.FxCop|Any CPU.ActiveCfg = Release|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {137906EA-15FE-4AD8-A6A0-27528F0477D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -533,7 +529,7 @@ Global {AB3C207C-0126-4143-8D62-1119DF80D366} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {EA4F1DA7-F2AB-4384-9AA4-9B756E2026B1} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {C889167C-E52C-4A65-A419-224B3D1B957D} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} - {848126A0-9C88-415A-868F-F5F03449D0B6} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} + {137906EA-15FE-4AD8-A6A0-27528F0477D6} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5} {ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} {6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA} diff --git a/src/Orchard/Caching/Weak.cs b/src/Orchard/Caching/Weak.cs index ce8ba0c61..fbab6c623 100644 --- a/src/Orchard/Caching/Weak.cs +++ b/src/Orchard/Caching/Weak.cs @@ -1,23 +1,20 @@ using System; -using System.Runtime.Serialization; namespace Orchard.Caching { - public class Weak : WeakReference { - public Weak(T target) - : base(target) { + public class Weak { + private readonly WeakReference _target; + + public Weak(T target) { + _target = new WeakReference(target); } - public Weak(T target, bool trackResurrection) - : base(target, trackResurrection) { + public Weak(T target, bool trackResurrection) { + _target = new WeakReference(target, trackResurrection); } - protected Weak(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - - public new T Target { - get { return (T)base.Target; } - set { base.Target = value; } + public T Target { + get { return (T)_target.Target; } + set { _target.Target = value; } } } -} +} \ No newline at end of file diff --git a/src/Orchard/Commands/CommandModule.cs b/src/Orchard/Commands/CommandModule.cs index c857232b5..fb9c192e1 100644 --- a/src/Orchard/Commands/CommandModule.cs +++ b/src/Orchard/Commands/CommandModule.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using Autofac; using Autofac.Core; diff --git a/src/Orchard/ContentManagement/DefaultContentDisplay.cs b/src/Orchard/ContentManagement/DefaultContentDisplay.cs index 554e1e2a2..19a2b2c7c 100644 --- a/src/Orchard/ContentManagement/DefaultContentDisplay.cs +++ b/src/Orchard/ContentManagement/DefaultContentDisplay.cs @@ -1,16 +1,11 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Web.Routing; -using ClaySharp; using ClaySharp.Implementation; -using Microsoft.CSharp.RuntimeBinder; using Orchard.ContentManagement.Handlers; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.Logging; -using Orchard.Mvc; using Orchard.Themes; using Orchard.UI.Zones; @@ -19,24 +14,18 @@ namespace Orchard.ContentManagement { private readonly Lazy> _handlers; private readonly IShapeFactory _shapeFactory; private readonly IShapeTableManager _shapeTableManager; - private readonly IWorkContextAccessor _workContextAccessor; - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly Lazy _themeService; + private readonly Lazy _themeService; private readonly RequestContext _requestContext; public DefaultContentDisplay( Lazy> handlers, IShapeFactory shapeFactory, IShapeTableManager shapeTableManager, - IWorkContextAccessor workContextAccessor, - IHttpContextAccessor httpContextAccessor, - Lazy themeService, + Lazy themeService, RequestContext requestContext) { _handlers = handlers; _shapeFactory = shapeFactory; _shapeTableManager = shapeTableManager; - _workContextAccessor = workContextAccessor; - _httpContextAccessor = httpContextAccessor; _themeService = themeService; _requestContext = requestContext; Logger = NullLogger.Instance; @@ -44,14 +33,6 @@ namespace Orchard.ContentManagement { public ILogger Logger { get; set; } - static readonly CallSiteCollection _shapeHelperCalls = new CallSiteCollection(shapeTypeName => Binder.InvokeMember( - CSharpBinderFlags.None, - shapeTypeName, - Enumerable.Empty(), - null, - new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); - - public dynamic BuildDisplay(IContent content, string displayType) { var contentTypeDefinition = content.ContentItem.TypeDefinition; string stereotype; @@ -118,7 +99,7 @@ namespace Orchard.ContentManagement { //var workContext = _workContextAccessor.GetContext(); //var theme = workContext.CurrentTheme; var theme = _themeService.Value.GetRequestTheme(_requestContext); - var shapeTable = _shapeTableManager.GetShapeTable(theme.ThemeName); + var shapeTable = _shapeTableManager.GetShapeTable(theme.Name); ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ShapePlacementContext { diff --git a/src/Orchard/Data/Migration/DataMigrationManager.cs b/src/Orchard/Data/Migration/DataMigrationManager.cs index 4ddf0ba2d..8d1adebac 100644 --- a/src/Orchard/Data/Migration/DataMigrationManager.cs +++ b/src/Orchard/Data/Migration/DataMigrationManager.cs @@ -86,8 +86,7 @@ namespace Orchard.Data.Migration { Logger.Information("Updating feature: {0}", feature); // proceed with dependent features first, whatever the module it's in - var dependencies = ShellStateCoordinator.OrderByDependencies(_extensionManager.AvailableExtensions() - .SelectMany(ext => ext.Features)) + var dependencies = _extensionManager.AvailableFeatures() .Where(f => String.Equals(f.Name, feature, StringComparison.OrdinalIgnoreCase)) .Where(f => f.Dependencies != null) .SelectMany( f => f.Dependencies ) @@ -189,7 +188,7 @@ namespace Orchard.Data.Migration { .ToList(); foreach (var migration in migrations.OfType()) { - migration.SchemaBuilder = new SchemaBuilder(_interpreter, migration.Feature.Descriptor.Name.Replace(".", "_") + "_"); + migration.SchemaBuilder = new SchemaBuilder(_interpreter, migration.Feature.Descriptor.Name, (s) => s.Replace(".", "_") + "_"); migration.ContentDefinitionManager = _contentDefinitionManager; } diff --git a/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs b/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs index 0744e6d3c..ea2fa5c26 100644 --- a/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs +++ b/src/Orchard/Data/Migration/Generator/SchemaCommandGenerator.cs @@ -41,8 +41,7 @@ namespace Orchard.Data.Migration.Generator { /// Generates SchemaCommand instances in order to create the schema for a specific feature /// public IEnumerable GetCreateFeatureCommands(string feature, bool drop) { - var dependencies = ShellStateCoordinator.OrderByDependencies(_extensionManager.AvailableExtensions() - .SelectMany(ext => ext.Features)) + var dependencies = _extensionManager.AvailableFeatures() .Where(f => String.Equals(f.Name, feature, StringComparison.OrdinalIgnoreCase)) .Where(f => f.Dependencies != null) .SelectMany(f => f.Dependencies) diff --git a/src/Orchard/Data/Migration/Schema/SchemaBuilder.cs b/src/Orchard/Data/Migration/Schema/SchemaBuilder.cs index cfe318267..af73145b8 100644 --- a/src/Orchard/Data/Migration/Schema/SchemaBuilder.cs +++ b/src/Orchard/Data/Migration/Schema/SchemaBuilder.cs @@ -5,28 +5,30 @@ namespace Orchard.Data.Migration.Schema { public class SchemaBuilder { private readonly IDataMigrationInterpreter _interpreter; private readonly string _featurePrefix; + private readonly Func _formatPrefix; - public SchemaBuilder(IDataMigrationInterpreter interpreter, string featurePrefix = null) { + public SchemaBuilder(IDataMigrationInterpreter interpreter, string featurePrefix = null, Func formatPrefix = null) { _interpreter = interpreter; - _featurePrefix = featurePrefix; + _featurePrefix = featurePrefix ?? String.Empty; + _formatPrefix = formatPrefix ?? (s => s ?? String.Empty); } public SchemaBuilder CreateTable(string name, Action table) { - var createTable = new CreateTableCommand(String.Concat(_featurePrefix, name)); + var createTable = new CreateTableCommand(String.Concat(_formatPrefix(_featurePrefix), name)); table(createTable); Run(createTable); return this; } public SchemaBuilder AlterTable(string name, Action table) { - var alterTable = new AlterTableCommand(String.Concat(_featurePrefix, name)); + var alterTable = new AlterTableCommand(String.Concat(_formatPrefix(_featurePrefix), name)); table(alterTable); Run(alterTable); return this; } public SchemaBuilder DropTable(string name) { - var deleteTable = new DropTableCommand(String.Concat(_featurePrefix, name)); + var deleteTable = new DropTableCommand(String.Concat(_formatPrefix(_featurePrefix), name)); Run(deleteTable); return this; } @@ -45,13 +47,37 @@ namespace Orchard.Data.Migration.Schema { } public SchemaBuilder CreateForeignKey(string name, string srcTable, string[] srcColumns, string destTable, string[] destColumns) { - var command = new CreateForeignKeyCommand(name, String.Concat(_featurePrefix, srcTable), srcColumns, String.Concat(_featurePrefix, destTable), destColumns); + var command = new CreateForeignKeyCommand(name, String.Concat(_formatPrefix(_featurePrefix), srcTable), srcColumns, String.Concat(_formatPrefix(_featurePrefix), destTable), destColumns); + Run(command); + return this; + } + + public SchemaBuilder CreateForeignKey(string name, string srcModule, string srcTable, string[] srcColumns, string destTable, string[] destColumns) { + var command = new CreateForeignKeyCommand(name, String.Concat(_formatPrefix(srcModule), srcTable), srcColumns, String.Concat(_formatPrefix(_featurePrefix), destTable), destColumns); + Run(command); + return this; + } + + public SchemaBuilder CreateForeignKey(string name, string srcTable, string[] srcColumns, string destModule, string destTable, string[] destColumns) { + var command = new CreateForeignKeyCommand(name, String.Concat(_formatPrefix(_featurePrefix), srcTable), srcColumns, String.Concat(_formatPrefix(destModule), destTable), destColumns); + Run(command); + return this; + } + + public SchemaBuilder CreateForeignKey(string name, string srcModule, string srcTable, string[] srcColumns, string destModule, string destTable, string[] destColumns) { + var command = new CreateForeignKeyCommand(name, String.Concat(_formatPrefix(srcModule), srcTable), srcColumns, String.Concat(_formatPrefix(destModule), destTable), destColumns); Run(command); return this; } public SchemaBuilder DropForeignKey(string srcTable, string name) { - var command = new DropForeignKeyCommand(String.Concat(_featurePrefix, srcTable), name); + var command = new DropForeignKeyCommand(String.Concat(_formatPrefix(_featurePrefix), srcTable), name); + Run(command); + return this; + } + + public SchemaBuilder DropForeignKey(string srcModule, string srcTable, string name) { + var command = new DropForeignKeyCommand(String.Concat(_formatPrefix(srcModule), srcTable), name); Run(command); return this; } diff --git a/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs b/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs index c2f68fc30..b10395cdb 100644 --- a/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs +++ b/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs @@ -9,16 +9,12 @@ using Orchard.Utility; namespace Orchard.DisplayManagement.Descriptors { - public interface IFeatureMetadata { - Feature Feature { get; } - } - public class DefaultShapeTableManager : IShapeTableManager { - private readonly IEnumerable> _bindingStrategies; + private readonly IEnumerable> _bindingStrategies; private readonly IExtensionManager _extensionManager; public DefaultShapeTableManager( - IEnumerable> bindingStrategies, + IEnumerable> bindingStrategies, IExtensionManager extensionManager) { _extensionManager = extensionManager; _bindingStrategies = bindingStrategies; @@ -30,7 +26,10 @@ namespace Orchard.DisplayManagement.Descriptors { return _tables.GetOrAdd(themeName ?? "", x => { var builderFactory = new ShapeTableBuilderFactory(); foreach (var bindingStrategy in _bindingStrategies) { - var strategyDefaultFeature = bindingStrategy.Metadata.Feature; + Feature strategyDefaultFeature = bindingStrategy.Metadata.ContainsKey("Feature") ? + (Feature) bindingStrategy.Metadata["Feature"] : + null; + var builder = builderFactory.CreateTableBuilder(strategyDefaultFeature); bindingStrategy.Value.Discover(builder); } diff --git a/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs index 4ca7fba14..6f87b85bd 100644 --- a/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs +++ b/src/Orchard/DisplayManagement/Implementation/DefaultDisplayManager.cs @@ -53,7 +53,7 @@ namespace Orchard.DisplayManagement.Implementation { return CoerceHtmlString(context.Value); var workContext = _workContextAccessor.GetContext(context.ViewContext); - var shapeTable = _shapeTableManager.GetShapeTable(workContext.CurrentTheme.ThemeName); + var shapeTable = _shapeTableManager.GetShapeTable(workContext.CurrentTheme.Name); var displayingContext = new ShapeDisplayingContext { Shape = shape, diff --git a/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs index a4f37df3a..38d365fac 100644 --- a/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs +++ b/src/Orchard/Environment/AutofacUtil/DynamicProxy2/ConstructorFinderWrapper.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; using Autofac.Core.Activators.Reflection; diff --git a/src/Orchard/Environment/AutofacUtil/LifetimeScopeContainer.cs b/src/Orchard/Environment/AutofacUtil/LifetimeScopeContainer.cs index 1d9ffe0e6..bd6a96e08 100644 --- a/src/Orchard/Environment/AutofacUtil/LifetimeScopeContainer.cs +++ b/src/Orchard/Environment/AutofacUtil/LifetimeScopeContainer.cs @@ -19,7 +19,7 @@ namespace Orchard.Environment.AutofacUtil { get { return _lifetimeScope.ComponentRegistry; } } - public void Dispose() { + public void Dispose() { } public ILifetimeScope BeginLifetimeScope() { diff --git a/src/Orchard/Environment/DefaultOrchardHost.cs b/src/Orchard/Environment/DefaultOrchardHost.cs index 07fbcd8e7..7d5f0b5d1 100644 --- a/src/Orchard/Environment/DefaultOrchardHost.cs +++ b/src/Orchard/Environment/DefaultOrchardHost.cs @@ -1,6 +1,5 @@ using System.Linq; using System.Threading; -using System.Web.Mvc; using System.Collections.Generic; using Orchard.Caching; using Orchard.Environment.Configuration; @@ -11,10 +10,7 @@ using Orchard.Environment.Descriptor; using Orchard.Environment.Descriptor.Models; using Orchard.Localization; using Orchard.Logging; -using Orchard.Mvc; -using Orchard.Mvc.ViewEngines; using Orchard.Utility.Extensions; -using Autofac; namespace Orchard.Environment { public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler { @@ -62,7 +58,7 @@ namespace Orchard.Environment { } void IOrchardHost.ReloadExtensions() { - _current = null; + DisposeShellContext(); } void IOrchardHost.BeginRequest() { @@ -145,11 +141,20 @@ namespace Orchard.Environment { ctx => { _extensionLoaderCoordinator.MonitorExtensions(ctx.Monitor); _hostLocalRestart.Monitor(ctx.Monitor); - _current = null; + DisposeShellContext(); return ""; }); } + private void DisposeShellContext() { + if (_current != null) { + foreach (var shellContext in _current) { + shellContext.Shell.Terminate(); + } + _current = null; + } + } + protected virtual void BeginRequest() { MonitorExtensions(); BuildCurrent(); @@ -176,11 +181,11 @@ namespace Orchard.Environment { } void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) { - _current = null; + DisposeShellContext(); } void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor) { - _current = null; + DisposeShellContext(); } } } diff --git a/src/Orchard/Environment/DefaultOrchardShell.cs b/src/Orchard/Environment/DefaultOrchardShell.cs index b263f909b..df740d677 100644 --- a/src/Orchard/Environment/DefaultOrchardShell.cs +++ b/src/Orchard/Environment/DefaultOrchardShell.cs @@ -1,10 +1,7 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Web.Mvc; using Autofac.Features.OwnedInstances; -using Orchard.Environment.Extensions.Models; using Orchard.Logging; using Orchard.Mvc.ModelBinders; using Orchard.Mvc.Routes; @@ -17,21 +14,18 @@ namespace Orchard.Environment { private readonly IRoutePublisher _routePublisher; private readonly IEnumerable _modelBinderProviders; private readonly IModelBinderPublisher _modelBinderPublisher; - private readonly ViewEngineCollection _viewEngines; public DefaultOrchardShell( Func> eventsFactory, IEnumerable routeProviders, IRoutePublisher routePublisher, IEnumerable modelBinderProviders, - IModelBinderPublisher modelBinderPublisher, - ViewEngineCollection viewEngines) { + IModelBinderPublisher modelBinderPublisher) { _eventsFactory = eventsFactory; _routeProviders = routeProviders; _routePublisher = routePublisher; _modelBinderProviders = modelBinderProviders; _modelBinderPublisher = modelBinderPublisher; - _viewEngines = viewEngines; Logger = NullLogger.Instance; } @@ -42,8 +36,6 @@ namespace Orchard.Environment { _routePublisher.Publish(_routeProviders.SelectMany(provider => provider.GetRoutes())); _modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders())); - //AddOrchardLocationsFormats(); - using (var events = _eventsFactory()) { events.Value.Activated(); } @@ -54,62 +46,5 @@ namespace Orchard.Environment { events.Value.Terminating(); } } - - /// - /// Adds view locations formats for non-themed views in custom orchard modules. - /// - private void AddOrchardLocationsFormats() { - - IEnumerable orchardMasterLocationFormats = new[] { - "~/Modules/{2}/Views/{1}/{0}.master", - "~/Modules/{2}/Views/Shared/{0}.master", - "~/Themes/{2}/Views/{1}/{0}.master", - "~/Themes/{2}/Views/Shared/{0}.master", - "~/Core/{2}/Views/{1}/{0}.master", - "~/Core/{2}/Views/Shared/{0}.master", - "~/Areas/{2}/Views/{1}/{0}.master", - "~/Areas/{2}/Views/Shared/{0}.master", - }; - - IEnumerable orchardLocationFormats = new[] { - "~/Modules/{2}/Views/{1}/{0}.aspx", - "~/Modules/{2}/Views/{1}/{0}.ascx", - "~/Modules/{2}/Views/Shared/{0}.aspx", - "~/Modules/{2}/Views/Shared/{0}.ascx", - "~/Themes/{2}/Views/{1}/{0}.aspx", - "~/Themes/{2}/Views/{1}/{0}.ascx", - "~/Themes/{2}/Views/Shared/{0}.aspx", - "~/Themes/{2}/Views/Shared/{0}.ascx", - "~/Core/{2}/Views/{1}/{0}.aspx", - "~/Core/{2}/Views/{1}/{0}.ascx", - "~/Core/{2}/Views/Shared/{0}.aspx", - "~/Core/{2}/Views/Shared/{0}.ascx", - "~/Areas/{2}/Views/{1}/{0}.aspx", - "~/Areas/{2}/Views/{1}/{0}.ascx", - "~/Areas/{2}/Views/Shared/{0}.aspx", - "~/Areas/{2}/Views/Shared/{0}.ascx", - }; - - var viewEngine = _viewEngines.OfType().Single(); - viewEngine.AreaMasterLocationFormats = orchardMasterLocationFormats - .Concat(viewEngine.AreaMasterLocationFormats) - .Distinct() - .ToArray(); - viewEngine.AreaViewLocationFormats = orchardLocationFormats - .Concat(viewEngine.AreaViewLocationFormats) - .Distinct() - .ToArray(); - viewEngine.AreaPartialViewLocationFormats = orchardLocationFormats - .Concat(viewEngine.AreaPartialViewLocationFormats) - .Distinct() - .ToArray(); - } - - private static string ModelsLocationFormat(ExtensionDescriptor descriptor) { - return Path.Combine(Path.Combine(descriptor.Location, descriptor.Name), "Views/Shared/{0}.ascx"); - } - - - } } diff --git a/src/Orchard/Environment/Extensions/ExtensionManager.cs b/src/Orchard/Environment/Extensions/ExtensionManager.cs index f8a51dad2..1560913ce 100644 --- a/src/Orchard/Environment/Extensions/ExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/ExtensionManager.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Web; -using ICSharpCode.SharpZipLib.Zip; -using Orchard.Environment.Descriptor.Models; using Orchard.Environment.Extensions.Folders; -using Orchard.Environment.Extensions.Helpers; using Orchard.Environment.Extensions.Loaders; using Orchard.Environment.Extensions.Models; using Orchard.Localization; @@ -18,6 +14,7 @@ namespace Orchard.Environment.Extensions { public class ExtensionManager : IExtensionManager { private readonly IEnumerable _folders; private readonly IEnumerable _loaders; + private IEnumerable _featureDescriptors; public Localizer T { get; set; } public ILogger Logger { get; set; } @@ -31,14 +28,20 @@ namespace Orchard.Environment.Extensions { // This method does not load extension types, simply parses extension manifests from // the filesystem. + public ExtensionDescriptor GetExtension(string name) { + return AvailableExtensions().FirstOrDefault(x => x.Name == name); + } + public IEnumerable AvailableExtensions() { return _folders.SelectMany(folder => folder.AvailableExtensions()); } public IEnumerable AvailableFeatures() { - var featureDescriptors = AvailableExtensions().SelectMany(ext => ext.Features); - var featureDescriptorsOrdered = featureDescriptors.OrderByDependencies(HasDependency); - return featureDescriptorsOrdered.ToReadOnlyCollection(); + if (_featureDescriptors == null || _featureDescriptors.Count() == 0) { + _featureDescriptors = AvailableExtensions().SelectMany(ext => ext.Features).OrderByDependencies(HasDependency).ToReadOnlyCollection(); + return _featureDescriptors; + } + return _featureDescriptors; } /// @@ -65,7 +68,7 @@ namespace Orchard.Environment.Extensions { } private IEnumerable LoadedExtensions() { - foreach ( var descriptor in AvailableExtensions() ) { + foreach (var descriptor in AvailableExtensions()) { ExtensionEntry entry = null; try { entry = BuildEntry(descriptor); @@ -138,65 +141,6 @@ namespace Orchard.Environment.Extensions { return null; } - public void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle) { - if (String.IsNullOrEmpty(extensionType)) { - throw new ArgumentException(T("extensionType was null or empty").ToString()); - } - string targetFolder; - if (String.Equals(extensionType, "Theme", StringComparison.OrdinalIgnoreCase)) { - targetFolder = PathHelpers.GetPhysicalPath("~/Themes"); - } - else if (String.Equals(extensionType, "Module", StringComparison.OrdinalIgnoreCase)) { - targetFolder = PathHelpers.GetPhysicalPath("~/Modules"); - } - else { - throw new ArgumentException(T("extensionType was not recognized").ToString()); - } - int postedFileLength = extensionBundle.ContentLength; - Stream postedFileStream = extensionBundle.InputStream; - byte[] postedFileData = new byte[postedFileLength]; - postedFileStream.Read(postedFileData, 0, postedFileLength); - - using (var memoryStream = new MemoryStream(postedFileData)) { - var fileInflater = new ZipInputStream(memoryStream); - ZipEntry entry; - while ((entry = fileInflater.GetNextEntry()) != null) { - string directoryName = Path.GetDirectoryName(entry.Name); - if (!Directory.Exists(Path.Combine(targetFolder, directoryName))) { - Directory.CreateDirectory(Path.Combine(targetFolder, directoryName)); - } - - if (!entry.IsDirectory && entry.Name.Length > 0) { - var len = Convert.ToInt32(entry.Size); - var extractedBytes = new byte[len]; - fileInflater.Read(extractedBytes, 0, len); - File.WriteAllBytes(Path.Combine(targetFolder, entry.Name), extractedBytes); - } - } - } - } - - public void UninstallExtension(string extensionType, string extensionName) { - if (String.IsNullOrEmpty(extensionType)) { - throw new ArgumentException(T("extensionType was null or empty").ToString()); - } - string targetFolder; - if (String.Equals(extensionType, "Theme", StringComparison.OrdinalIgnoreCase)) { - targetFolder = PathHelpers.GetPhysicalPath("~/Themes"); - } - else if (String.Equals(extensionType, "Module", StringComparison.OrdinalIgnoreCase)) { - targetFolder = PathHelpers.GetPhysicalPath("~/Modules"); - } - else { - throw new ArgumentException(T("extensionType was not recognized").ToString()); - } - targetFolder = Path.Combine(targetFolder, extensionName); - if (!Directory.Exists(targetFolder)) { - throw new ArgumentException(T("extension was not found").ToString()); - } - Directory.Delete(targetFolder, true); - } - private ExtensionEntry BuildEntry(ExtensionDescriptor descriptor) { foreach (var loader in _loaders) { ExtensionEntry entry = loader.Load(descriptor); diff --git a/src/Orchard/Environment/Extensions/IExtensionManager.cs b/src/Orchard/Environment/Extensions/IExtensionManager.cs index b4917f132..d12f4a1ab 100644 --- a/src/Orchard/Environment/Extensions/IExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/IExtensionManager.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using System.Web; using Orchard.Environment.Descriptor.Models; using Orchard.Environment.Extensions.Models; @@ -8,10 +7,10 @@ namespace Orchard.Environment.Extensions { public interface IExtensionManager { IEnumerable AvailableExtensions(); IEnumerable AvailableFeatures(); - IEnumerable LoadFeatures(IEnumerable featureDescriptors); - void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle); - void UninstallExtension(string extensionType, string extensionName); + ExtensionDescriptor GetExtension(string name); + + IEnumerable LoadFeatures(IEnumerable featureDescriptors); } public static class ExtensionManagerExtensions { diff --git a/src/Orchard/Environment/Extensions/Models/Extension.cs b/src/Orchard/Environment/Extensions/Models/Extension.cs deleted file mode 100644 index 3043c42e3..000000000 --- a/src/Orchard/Environment/Extensions/Models/Extension.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Orchard.Environment.Extensions.Models { - public class Extension { - } -} \ No newline at end of file diff --git a/src/Orchard/Environment/Extensions/Models/ExtensionDescriptor.cs b/src/Orchard/Environment/Extensions/Models/ExtensionDescriptor.cs index 667b8ab1e..ba2452a2f 100644 --- a/src/Orchard/Environment/Extensions/Models/ExtensionDescriptor.cs +++ b/src/Orchard/Environment/Extensions/Models/ExtensionDescriptor.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace Orchard.Environment.Extensions.Models { public class ExtensionDescriptor { @@ -26,7 +27,7 @@ namespace Orchard.Environment.Extensions.Models { public string WebSite { get; set; } public string Tags { get; set; } public string AntiForgery { get; set; } - public string Zones { get; set; } + public string Zones { get; set; } public string BaseTheme { get; set; } public IEnumerable Features { get; set; } diff --git a/src/Orchard/Environment/Extensions/Models/FeatureDescriptor.cs b/src/Orchard/Environment/Extensions/Models/FeatureDescriptor.cs index 6f25ea09d..7f67705f7 100644 --- a/src/Orchard/Environment/Extensions/Models/FeatureDescriptor.cs +++ b/src/Orchard/Environment/Extensions/Models/FeatureDescriptor.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; namespace Orchard.Environment.Extensions.Models { diff --git a/src/Orchard/Environment/Features/FeatureManager.cs b/src/Orchard/Environment/Features/FeatureManager.cs new file mode 100644 index 000000000..b4f347f71 --- /dev/null +++ b/src/Orchard/Environment/Features/FeatureManager.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Environment.Descriptor; +using Orchard.Environment.Descriptor.Models; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; + +namespace Orchard.Environment.Features { + public interface IFeatureManager : IDependency { + IEnumerable GetAvailableFeatures(); + IEnumerable GetEnabledFeatures(); + + void EnableFeatures(IEnumerable featureNames); + void DisableFeatures(IEnumerable featureNames); + } + + public class FeatureManager : IFeatureManager { + private readonly IExtensionManager _extensionManager; + private readonly ShellDescriptor _shellDescriptor; + private readonly IShellDescriptorManager _shellDescriptorManager; + + public FeatureManager( + IExtensionManager extensionManager, + ShellDescriptor shellDescriptor, + IShellDescriptorManager shellDescriptorManager) { + _extensionManager = extensionManager; + _shellDescriptor = shellDescriptor; + _shellDescriptorManager = shellDescriptorManager; + } + + public IEnumerable GetAvailableFeatures() { + return _extensionManager.AvailableFeatures(); + } + + public IEnumerable GetEnabledFeatures() { + throw new NotImplementedException(); + } + + public void EnableFeatures(IEnumerable featureNames) { + var currentShellDescriptor = _shellDescriptorManager.GetShellDescriptor(); + + var updatedFeatures = currentShellDescriptor.Features + .Union(featureNames + .Where(name => !currentShellDescriptor.Features.Any(sf => sf.Name == name)) + .Select(name => new ShellFeature {Name = name})); + + _shellDescriptorManager.UpdateShellDescriptor( + currentShellDescriptor.SerialNumber, + updatedFeatures, + currentShellDescriptor.Parameters); + } + + public void DisableFeatures(IEnumerable featureNames) { + var currentShellDescriptor = _shellDescriptorManager.GetShellDescriptor(); + + var updatedFeatures = currentShellDescriptor.Features + .Where(sf => !featureNames.Contains(sf.Name)); + + _shellDescriptorManager.UpdateShellDescriptor( + currentShellDescriptor.SerialNumber, + updatedFeatures, + currentShellDescriptor.Parameters); + } + + + //private void DisableThemeFeatures(string themeName) { + // var themes = new Queue(); + // while (themeName != null) { + // if (themes.Contains(themeName)) + // throw new InvalidOperationException(T("The theme \"{0}\" is already in the stack of themes that need features disabled.", themeName).Text); + // var theme = GetThemeByName(themeName); + // if (theme == null) + // break; + // themes.Enqueue(themeName); + + // themeName = !string.IsNullOrWhiteSpace(theme.BaseTheme) + // ? theme.BaseTheme + // : null; + + // } + + // while (themes.Count > 0) + // _moduleService.DisableFeatures(new[] { themes.Dequeue() }); + //} + + //private void EnableThemeFeatures(string themeName) { + // var themes = new Stack(); + // while (themeName != null) { + // if (themes.Contains(themeName)) + // throw new InvalidOperationException(T("The theme \"{0}\" is already in the stack of themes that need features enabled.", themeName).Text); + // themes.Push(themeName); + + // var theme = GetThemeByName(themeName); + // themeName = !string.IsNullOrWhiteSpace(theme.BaseTheme) + // ? theme.BaseTheme + // : null; + // } + + // while (themes.Count > 0) + // _moduleService.EnableFeatures(new[] { themes.Pop() }); + //} + + //private bool DoEnableTheme(string themeName) { + // if (string.IsNullOrWhiteSpace(themeName)) + // return false; + + // //todo: (heskew) need messages given in addition to all of these early returns so something meaningful can be presented to the user + // var themeToEnable = GetThemeByName(themeName); + // if (themeToEnable == null) + // return false; + + // // ensure all base themes down the line are present and accounted for + // //todo: (heskew) dito on the need of a meaningful message + // if (!AllBaseThemesAreInstalled(themeToEnable.BaseTheme)) + // return false; + + // // enable all theme features + // EnableThemeFeatures(themeToEnable.Name); + // return true; + //} + + } +} diff --git a/src/Orchard/Environment/IHostEnvironment.cs b/src/Orchard/Environment/IHostEnvironment.cs index 772ef04fa..c1cba668a 100644 --- a/src/Orchard/Environment/IHostEnvironment.cs +++ b/src/Orchard/Environment/IHostEnvironment.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Reflection; using System.Web; using System.Web.Hosting; using Orchard.Services; @@ -36,7 +37,7 @@ namespace Orchard.Environment { } public bool IsAssemblyLoaded(string name) { - return AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name == name); + return AppDomain.CurrentDomain.GetAssemblies().Any(assembly => new AssemblyName(assembly.FullName).Name == name); } public void RestartAppDomain() { diff --git a/src/Orchard/Environment/OrchardServices.cs b/src/Orchard/Environment/OrchardServices.cs index 42f9f492f..0f904f392 100644 --- a/src/Orchard/Environment/OrchardServices.cs +++ b/src/Orchard/Environment/OrchardServices.cs @@ -10,14 +10,17 @@ namespace Orchard.Environment { [UsedImplicitly] public class OrchardServices : IOrchardServices { private readonly Lazy _shapeFactory; + private readonly IWorkContextAccessor _workContextAccessor; public OrchardServices( IContentManager contentManager, ITransactionManager transactionManager, IAuthorizer authorizer, INotifier notifier, - Lazy shapeFactory) { + Lazy shapeFactory, + IWorkContextAccessor workContextAccessor) { _shapeFactory = shapeFactory; + _workContextAccessor = workContextAccessor; ContentManager = contentManager; TransactionManager = transactionManager; Authorizer = authorizer; @@ -29,5 +32,6 @@ namespace Orchard.Environment { public IAuthorizer Authorizer { get; private set; } public INotifier Notifier { get; private set; } public dynamic New { get { return _shapeFactory.Value; } } + public WorkContext WorkContext { get { return _workContextAccessor.GetContext(); } } } } diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 5917f4d4c..885fa1a43 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -7,7 +7,6 @@ using System.Web.Mvc; using Autofac; using Autofac.Configuration; using Orchard.Caching; -using Orchard.Environment.AutofacUtil; using Orchard.Environment.Configuration; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Compilers; diff --git a/src/Orchard/Environment/ShellBuilders/ShellContainerFactory.cs b/src/Orchard/Environment/ShellBuilders/ShellContainerFactory.cs index 24a108c9c..c189ced00 100644 --- a/src/Orchard/Environment/ShellBuilders/ShellContainerFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/ShellContainerFactory.cs @@ -89,10 +89,13 @@ namespace Orchard.Environment.ShellBuilders { } foreach (var item in blueprint.Controllers) { - var serviceKey = (item.AreaName + "/" + item.ControllerName).ToLowerInvariant(); + var serviceKeyName = (item.AreaName + "/" + item.ControllerName).ToLowerInvariant(); + var serviceKeyType = item.Type; RegisterType(builder, item) .EnableDynamicProxy(dynamicProxyContext) - .Keyed(serviceKey) + .Keyed(serviceKeyName) + .Keyed(serviceKeyType) + .WithMetadata("ControllerType", item.Type) .InstancePerDependency() .OnActivating(e => { var controller = e.Instance as Controller; diff --git a/src/Orchard/Environment/State/ShellStateCoordinator.cs b/src/Orchard/Environment/State/ShellStateCoordinator.cs index 441df6183..ff876a139 100644 --- a/src/Orchard/Environment/State/ShellStateCoordinator.cs +++ b/src/Orchard/Environment/State/ShellStateCoordinator.cs @@ -7,7 +7,6 @@ using Orchard.Environment.Extensions.Models; using Orchard.Environment.State.Models; using Orchard.Environment.Descriptor; using Orchard.Environment.Descriptor.Models; -using Orchard.Utility; namespace Orchard.Environment.State { public class ShellStateCoordinator : IShellStateManagerEventHandler, IShellDescriptorManagerEventHandler { @@ -102,7 +101,7 @@ namespace Orchard.Environment.State { var shellState = _stateManager.GetShellState(); // start with description of all declared features in order - order preserved with all merging - var orderedFeatureDescriptors = AllFeaturesInOrder(); + var orderedFeatureDescriptors = _extensionManager.AvailableFeatures(); // merge feature state into ordered list var orderedFeatureDescriptorsAndStates = orderedFeatureDescriptors @@ -176,19 +175,9 @@ namespace Orchard.Environment.State { FireApplyChangesIfNeeded(); } - private IEnumerable AllFeaturesInOrder() { - return OrderByDependencies(_extensionManager.AvailableExtensions().SelectMany(ext => ext.Features)); - } - static bool IsRising(ShellFeatureState state) { return state.InstallState == ShellFeatureState.State.Rising || state.EnableState == ShellFeatureState.State.Rising; } - - public static IEnumerable OrderByDependencies(IEnumerable descriptors) { - return descriptors.OrderByDependencies((item, dep) => - item.Dependencies != null && - item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, dep.Name))); - } } } diff --git a/src/Orchard/Events/IEventBusHandler.cs b/src/Orchard/Events/IEventBusHandler.cs deleted file mode 100644 index 3cb6e12be..000000000 --- a/src/Orchard/Events/IEventBusHandler.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Collections.Generic; - -namespace Orchard.Events { - public interface IEventBusHandler : IDependency { - void Process(string messageName, IDictionary eventData); - } -} diff --git a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs index 7f0817619..94109df69 100644 --- a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs +++ b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs @@ -1,4 +1,5 @@ -using System; +#if !AZURE +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -45,7 +46,7 @@ namespace Orchard.FileSystems.Media { public string GetPublicUrl(string path) { - return _publicPath + path.Replace(Path.DirectorySeparatorChar, '/'); + return Map(_publicPath + path.Replace(Path.DirectorySeparatorChar, '/')); } public IStorageFile GetFile(string path) { @@ -248,4 +249,5 @@ namespace Orchard.FileSystems.Media { } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/Orchard/IOrchardServices.cs b/src/Orchard/IOrchardServices.cs index ef68a0d09..0a99f23c7 100644 --- a/src/Orchard/IOrchardServices.cs +++ b/src/Orchard/IOrchardServices.cs @@ -10,5 +10,6 @@ namespace Orchard { IAuthorizer Authorizer { get; } INotifier Notifier { get; } dynamic New { get; } + WorkContext WorkContext { get; } } } diff --git a/src/Orchard/Localization/Commands/CultureCommands.cs b/src/Orchard/Localization/Commands/CultureCommands.cs index 841187d55..0f4158dc9 100644 --- a/src/Orchard/Localization/Commands/CultureCommands.cs +++ b/src/Orchard/Localization/Commands/CultureCommands.cs @@ -1,17 +1,15 @@ using System.Linq; -using JetBrains.Annotations; using Orchard.Commands; using Orchard.Localization.Services; -using Orchard.Settings; namespace Orchard.Localization.Commands { public class CultureCommands : DefaultOrchardCommandHandler { private readonly ICultureManager _cultureManager; + private readonly IOrchardServices _orchardServices; - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } - - public CultureCommands(ICultureManager cultureManager) { + public CultureCommands(ICultureManager cultureManager, IOrchardServices orchardServices) { _cultureManager = cultureManager; + _orchardServices = orchardServices; } [CommandHelp("cultures list \r\n\t" + "List site cultures")] @@ -28,7 +26,7 @@ namespace Orchard.Localization.Commands { [CommandHelp("cultures get site culture \r\n\t" + "Get culture for the site")] [CommandName("cultures get site culture")] public void GetSiteCulture() { - Context.Output.WriteLine(T("Site Culture is {0}", CurrentSite.SiteCulture)); + Context.Output.WriteLine(T("Site Culture is {0}", _orchardServices.WorkContext.CurrentSite.SiteCulture)); } [CommandHelp("cultures set site culture \r\n\t" + "Set culture for the site")] @@ -40,7 +38,7 @@ namespace Orchard.Localization.Commands { Context.Output.WriteLine(T("Supplied culture name {0} is not valid.", cultureName)); return; } - CurrentSite.SiteCulture = cultureName; + _orchardServices.WorkContext.CurrentSite.SiteCulture = cultureName; Context.Output.WriteLine(T("Site culture set to {0} successfully", cultureName)); } diff --git a/src/Orchard/Localization/Services/DefaultCultureManager.cs b/src/Orchard/Localization/Services/DefaultCultureManager.cs index 1ead59bc0..8ffc0d880 100644 --- a/src/Orchard/Localization/Services/DefaultCultureManager.cs +++ b/src/Orchard/Localization/Services/DefaultCultureManager.cs @@ -3,26 +3,27 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Web; -using JetBrains.Annotations; using Orchard.Caching; using Orchard.Data; using Orchard.Localization.Records; -using Orchard.Settings; namespace Orchard.Localization.Services { public class DefaultCultureManager : ICultureManager { private readonly IRepository _cultureRepository; private readonly IEnumerable _cultureSelectors; private readonly ISignals _signals; + private readonly IWorkContextAccessor _workContextAccessor; - public DefaultCultureManager(IRepository cultureRepository, IEnumerable cultureSelectors, ISignals signals) { + public DefaultCultureManager(IRepository cultureRepository, + IEnumerable cultureSelectors, + ISignals signals, + IWorkContextAccessor workContextAccessor) { _cultureRepository = cultureRepository; _cultureSelectors = cultureSelectors; _signals = signals; + _workContextAccessor = workContextAccessor; } - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } - public IEnumerable ListCultures() { var query = from culture in _cultureRepository.Table select culture.Culture; return query.ToList(); @@ -75,7 +76,7 @@ namespace Orchard.Localization.Services { } public string GetSiteCulture() { - return CurrentSite == null ? null : CurrentSite.SiteCulture; + return _workContextAccessor.GetContext().CurrentSite == null ? null : _workContextAccessor.GetContext().CurrentSite.SiteCulture; } // "" or diff --git a/src/Orchard/Localization/Services/SiteCultureSelector.cs b/src/Orchard/Localization/Services/SiteCultureSelector.cs index cac220fe6..b3e20761a 100644 --- a/src/Orchard/Localization/Services/SiteCultureSelector.cs +++ b/src/Orchard/Localization/Services/SiteCultureSelector.cs @@ -1,14 +1,16 @@ using System; using System.Web; -using JetBrains.Annotations; -using Orchard.Settings; namespace Orchard.Localization.Services { public class SiteCultureSelector : ICultureSelector { - protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } + private readonly IWorkContextAccessor _workContextAccessor; + + public SiteCultureSelector(IWorkContextAccessor workContextAccessor) { + _workContextAccessor = workContextAccessor; + } public CultureSelectorResult GetCulture(HttpContextBase context) { - string currentCultureName = CurrentSite.SiteCulture; + string currentCultureName = _workContextAccessor.GetContext().CurrentSite.SiteCulture; if (String.IsNullOrEmpty(currentCultureName)) { return null; diff --git a/src/Orchard/Logging/LoggingModule.cs b/src/Orchard/Logging/LoggingModule.cs index 5674b6fe2..b67da4b9c 100644 --- a/src/Orchard/Logging/LoggingModule.cs +++ b/src/Orchard/Logging/LoggingModule.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Security; +using System.Security.Permissions; using Autofac; using Autofac.Core; using Castle.Core.Logging; @@ -14,11 +16,17 @@ namespace Orchard.Logging { // by default, use Orchard's logger that delegates to Castle's logger factory moduleBuilder.RegisterType().As().InstancePerLifetimeScope(); - // by default, use Castle's TraceSource based logger factory - moduleBuilder.RegisterType().As().InstancePerLifetimeScope(); + try { + // by default, use Castle's TraceSource based logger factory + new SecurityPermission(SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy).Demand(); + moduleBuilder.RegisterType().As().InstancePerLifetimeScope(); + } catch (SecurityException) { + // if security model does not allow it, fall back to null logger factory + moduleBuilder.RegisterType().As().InstancePerLifetimeScope(); + } // call CreateLogger in response to the request for an ILogger implementation - moduleBuilder.Register((ctx, ps) => CreateLogger(ctx, ps)).As().InstancePerDependency(); + moduleBuilder.Register(CreateLogger).As().InstancePerDependency(); } protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { @@ -70,4 +78,4 @@ namespace Orchard.Logging { return loggerFactory.CreateLogger(containingType); } } -} +} \ No newline at end of file diff --git a/src/Orchard/Modules/IModule.cs b/src/Orchard/Modules/IModule.cs deleted file mode 100644 index 4bd53880c..000000000 --- a/src/Orchard/Modules/IModule.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using Orchard.Environment.Extensions.Models; - -namespace Orchard.Modules { - public interface IModule { - string ModuleName { get; set; } - string DisplayName { get; set; } - string Description { get; set; } - string Version { get; set; } - string Author { get; set; } - string HomePage { get; set; } - string Tags { get; set; } - IEnumerable Features { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard/Modules/IModuleFeature.cs b/src/Orchard/Modules/IModuleFeature.cs deleted file mode 100644 index cc59efa9b..000000000 --- a/src/Orchard/Modules/IModuleFeature.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Orchard.Environment.Extensions.Models; - -namespace Orchard.Modules { - public interface IModuleFeature { - FeatureDescriptor Descriptor { get; set; } - bool IsEnabled { get; set; } - } -} \ No newline at end of file diff --git a/src/Orchard/Modules/IModuleService.cs b/src/Orchard/Modules/IModuleService.cs deleted file mode 100644 index a4033bb84..000000000 --- a/src/Orchard/Modules/IModuleService.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; -using System.Web; - -namespace Orchard.Modules { - public interface IModuleService : IDependency { - IModule GetModuleByName(string moduleName); - IEnumerable GetInstalledModules(); - void InstallModule(HttpPostedFileBase file); - void UninstallModule(string moduleName); - IEnumerable GetAvailableFeatures(); - void EnableFeatures(IEnumerable featureNames); - void EnableFeatures(IEnumerable featureNames, bool force); - void DisableFeatures(IEnumerable featureNames); - void DisableFeatures(IEnumerable featureNames, bool force); - } -} \ No newline at end of file diff --git a/src/Orchard/Mvc/Html/ThemeExtensions.cs b/src/Orchard/Mvc/Html/ThemeExtensions.cs index 8ffe8d5f1..cb6da312d 100644 --- a/src/Orchard/Mvc/Html/ThemeExtensions.cs +++ b/src/Orchard/Mvc/Html/ThemeExtensions.cs @@ -1,7 +1,9 @@ -using System.Web.Mvc; +using System; +using System.Web.Mvc; using System.Web.Mvc.Html; using System.Web.UI; using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; using Orchard.Themes; using Orchard.Validation; @@ -15,12 +17,13 @@ namespace Orchard.Mvc.Html { helper.RenderPartial(viewName); } + [Obsolete("How do you know the request theme is the same as the place the theme template is rendering from?")] public static string ThemePath(this HtmlHelper helper, string path) { - return helper.ThemePath(helper.Resolve().GetRequestTheme(helper.ViewContext.RequestContext), path); + return helper.ThemePath(helper.Resolve().GetRequestTheme(helper.ViewContext.RequestContext), path); } - public static string ThemePath(this HtmlHelper helper, ITheme theme, string path) { - return helper.Resolve().GetThemeLocation(theme) + path; + public static string ThemePath(this HtmlHelper helper, ExtensionDescriptor theme, string path) { + return theme.Location + "/" + theme.Name + path; } } } diff --git a/src/Orchard/Mvc/OrchardControllerFactory.cs b/src/Orchard/Mvc/OrchardControllerFactory.cs index 8e85305e2..929cdf5fb 100644 --- a/src/Orchard/Mvc/OrchardControllerFactory.cs +++ b/src/Orchard/Mvc/OrchardControllerFactory.cs @@ -1,12 +1,32 @@ +using System; using System.Web.Mvc; using System.Web.Routing; using Autofac; using Autofac.Core; +using Autofac.Features.Metadata; namespace Orchard.Mvc { + public interface IControllerType { + Type ControllerType { get; } + } + public class OrchardControllerFactory : DefaultControllerFactory { - public override IController CreateController(RequestContext requestContext, string controllerName) { + bool TryResolve(WorkContext workContext, object serviceKey, out T instance ) { + if (workContext != null) { + var key = new KeyedService(serviceKey, typeof (T)); + object value; + if (workContext.Resolve().TryResolve(key, out value)) { + instance = (T) value; + return true; + } + } + + instance = default(T); + return false; + } + + protected override Type GetControllerType(RequestContext requestContext, string controllerName) { var routeData = requestContext.RouteData; // Determine the area name for the request, and fall back to stock orchard controllers @@ -15,18 +35,24 @@ namespace Orchard.Mvc { // Service name pattern matches the identification strategy var serviceKey = (areaName + "/" + controllerName).ToLowerInvariant(); - // Now that the request container is known - try to resolve the controller - object controller; - var service = new KeyedService(serviceKey, typeof(IController)); - + // Now that the request container is known - try to resolve the controller information + Lazy info; var workContext = requestContext.GetWorkContext(); - - if (workContext != null && - workContext.Resolve().TryResolve(service, out controller)) { - return (IController)controller; + if (TryResolve(workContext, serviceKey, out info)) { + return info.Metadata.ControllerType; } - return base.CreateController(requestContext, controllerName); + return null; + } + + protected override IController GetControllerInstance(RequestContext requestContext, System.Type controllerType) { + IController controller; + var workContext = requestContext.GetWorkContext(); + if (TryResolve(workContext, controllerType, out controller)) { + return controller; + } + + return null; } public static string GetAreaName(RouteBase route) { diff --git a/src/Orchard/Mvc/Routes/RoutePublisher.cs b/src/Orchard/Mvc/Routes/RoutePublisher.cs index c8175469c..5aa62c1a9 100644 --- a/src/Orchard/Mvc/Routes/RoutePublisher.cs +++ b/src/Orchard/Mvc/Routes/RoutePublisher.cs @@ -2,21 +2,26 @@ using System.Collections.Generic; using System.Linq; using System.Web.Routing; +using Autofac; +using Orchard.Environment; using Orchard.Environment.Configuration; namespace Orchard.Mvc.Routes { public class RoutePublisher : IRoutePublisher { private readonly RouteCollection _routeCollection; private readonly ShellSettings _shellSettings; - private readonly Func _shellRouteFactory; + private readonly ILifetimeScope _shellLifetimeScope; + private readonly IRunningShellTable _runningShellTable; public RoutePublisher( RouteCollection routeCollection, ShellSettings shellSettings, - Func shellRouteFactory) { + ILifetimeScope shellLifetimeScope, + IRunningShellTable runningShellTable) { _routeCollection = routeCollection; _shellSettings = shellSettings; - _shellRouteFactory = shellRouteFactory; + _shellLifetimeScope = shellLifetimeScope; + _runningShellTable = runningShellTable; } public void Publish(IEnumerable routes) { @@ -41,8 +46,8 @@ namespace Orchard.Mvc.Routes { // new routes are added foreach (var routeDescriptor in routesArray) { - //_routeCollection.Add(route.Name, _shellRouteFactory(_shellSettings.Name, route.Route)); - _routeCollection.Add(routeDescriptor.Name, _shellRouteFactory(routeDescriptor.Route)); + ShellRoute shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _shellLifetimeScope, _runningShellTable); + _routeCollection.Add(routeDescriptor.Name, shellRoute); } } } diff --git a/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemeAwareViewEngine.cs b/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemeAwareViewEngine.cs index 4ba2f9c18..e95e7a72f 100644 --- a/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemeAwareViewEngine.cs +++ b/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemeAwareViewEngine.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Web.Mvc; using Orchard.Environment.Descriptor.Models; using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; using Orchard.Themes; namespace Orchard.Mvc.ViewEngines.ThemeAwareness { @@ -64,15 +65,15 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness { return _configuredEnginesCache.BindBareEngines(() => new ViewEngineCollectionWrapper(_viewEngineProviders.Select(vep => vep.CreateBareViewEngine()))); } - private IViewEngine ShallowEngines(ITheme theme) { + private IViewEngine ShallowEngines(ExtensionDescriptor theme) { //return _configuredEnginesCache.BindShallowEngines(theme.ThemeName, () => new ViewEngineCollectionWrapper(_viewEngineProviders.Select(vep => vep.CreateBareViewEngine()))); return DeepEngines(theme); } - private IViewEngine DeepEngines(ITheme theme) { - return _configuredEnginesCache.BindDeepEngines(theme.ThemeName, () => { + private IViewEngine DeepEngines(ExtensionDescriptor theme) { + return _configuredEnginesCache.BindDeepEngines(theme.Name, () => { var engines = Enumerable.Empty(); - var themeLocation = _extensionManager.GetThemeLocation(theme); + var themeLocation = theme.Location + "/" + theme.Name; var themeParams = new CreateThemeViewEngineParams { VirtualPath = themeLocation }; engines = engines.Concat(_viewEngineProviders.Select(vep => vep.CreateThemeViewEngine(themeParams))); diff --git a/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemedViewResultFilter.cs b/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemedViewResultFilter.cs index 17b657666..ef079d052 100644 --- a/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemedViewResultFilter.cs +++ b/src/Orchard/Mvc/ViewEngines/ThemeAwareness/ThemedViewResultFilter.cs @@ -6,12 +6,12 @@ using Orchard.Themes; namespace Orchard.Mvc.ViewEngines.ThemeAwareness { public class ThemedViewResultFilter : FilterProvider, IResultFilter { - private readonly IThemeService _themeService; + private readonly IThemeManager _themeManager; private readonly WorkContext _workContext; private readonly ILayoutAwareViewEngine _layoutAwareViewEngine; - public ThemedViewResultFilter(IThemeService themeService, WorkContext workContext, ILayoutAwareViewEngine layoutAwareViewEngine) { - _themeService = themeService; + public ThemedViewResultFilter(IThemeManager themeManager, WorkContext workContext, ILayoutAwareViewEngine layoutAwareViewEngine) { + _themeManager = themeManager; _workContext = workContext; _layoutAwareViewEngine = layoutAwareViewEngine; Logger = NullLogger.Instance; @@ -26,7 +26,7 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness { } if (_workContext.CurrentTheme == null) { - _workContext.CurrentTheme = _themeService.GetRequestTheme(filterContext.RequestContext); + _workContext.CurrentTheme = _themeManager.GetRequestTheme(filterContext.RequestContext); } viewResultBase.ViewEngineCollection = new ViewEngineCollection(new[] { _layoutAwareViewEngine }); diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index f93a771dd..20fc0a2bc 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -114,6 +114,7 @@ ..\..\lib\linqnhibernate\NHibernate.Linq.dll + 3.5 @@ -174,6 +175,7 @@ + @@ -185,6 +187,7 @@ + @@ -658,18 +661,13 @@ - - - - - @@ -712,7 +710,6 @@ - @@ -774,17 +771,13 @@ - - - - - + diff --git a/src/Orchard/Properties/AssemblyInfo.cs b/src/Orchard/Properties/AssemblyInfo.cs index d576845a5..e8e04c110 100644 --- a/src/Orchard/Properties/AssemblyInfo.cs +++ b/src/Orchard/Properties/AssemblyInfo.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Runtime.InteropServices; +using System.Security; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -36,3 +37,4 @@ using System.Runtime.InteropServices; [assembly: AssemblyVersion("0.8.0")] [assembly: AssemblyFileVersion("0.8.0")] +[assembly: SecurityTransparent] \ No newline at end of file diff --git a/src/Orchard/Scripting/IScriptingManager.cs b/src/Orchard/Scripting/IScriptingManager.cs index 65256b0b4..06eea09bb 100644 --- a/src/Orchard/Scripting/IScriptingManager.cs +++ b/src/Orchard/Scripting/IScriptingManager.cs @@ -1,8 +1,12 @@ -namespace Orchard.Scripting { +using System; +using Microsoft.Scripting.Hosting; + +namespace Orchard.Scripting { public interface IScriptingManager : IDependency { dynamic GetVariable(string name); void SetVariable(string name, object value); dynamic ExecuteExpression(string expression); void ExecuteFile(string fileName); + dynamic ExecuteOperation(Func invoke); } } diff --git a/src/Orchard/Scripting/ScriptingManager.cs b/src/Orchard/Scripting/ScriptingManager.cs index 545134f20..4589dc63f 100644 --- a/src/Orchard/Scripting/ScriptingManager.cs +++ b/src/Orchard/Scripting/ScriptingManager.cs @@ -5,10 +5,12 @@ namespace Orchard.Scripting { public class ScriptingManager : IScriptingManager { private readonly IScriptingRuntime _scriptingRuntime; private Lazy _scope; + private Lazy _operations; public ScriptingManager(IScriptingRuntime scriptingRuntime) { _scriptingRuntime = scriptingRuntime; _scope = new Lazy(()=>_scriptingRuntime.CreateScope()); + _operations = new Lazy(()=>_scope.Value.Engine.CreateOperations()); } public dynamic GetVariable(string name) { @@ -23,6 +25,10 @@ namespace Orchard.Scripting { return _scriptingRuntime.ExecuteExpression(expression, _scope.Value); } + public dynamic ExecuteOperation(Func invoke) { + return invoke(_operations.Value); + } + public void ExecuteFile(string fileName) { _scriptingRuntime.ExecuteFile(fileName, _scope.Value); } diff --git a/src/Orchard/Security/Authorizer.cs b/src/Orchard/Security/Authorizer.cs index 09e249a66..a6c27b215 100644 --- a/src/Orchard/Security/Authorizer.cs +++ b/src/Orchard/Security/Authorizer.cs @@ -1,5 +1,4 @@ -using JetBrains.Annotations; -using Orchard.ContentManagement; +using Orchard.ContentManagement; using Orchard.Localization; using Orchard.Security.Permissions; using Orchard.UI.Notify; @@ -14,16 +13,18 @@ namespace Orchard.Security { public class Authorizer : IAuthorizer { private readonly IAuthorizationService _authorizationService; private readonly INotifier _notifier; + private readonly IWorkContextAccessor _workContextAccessor; public Authorizer( IAuthorizationService authorizationService, - INotifier notifier) { + INotifier notifier, + IWorkContextAccessor workContextAccessor) { _authorizationService = authorizationService; _notifier = notifier; + _workContextAccessor = workContextAccessor; T = NullLocalizer.Instance; } - protected virtual IUser CurrentUser { get; [UsedImplicitly] private set; } public Localizer T { get; set; } public bool Authorize(Permission permission) { @@ -35,17 +36,17 @@ namespace Orchard.Security { } public bool Authorize(Permission permission, IContent content, LocalizedString message) { - if (_authorizationService.TryCheckAccess(permission, CurrentUser, content)) + if (_authorizationService.TryCheckAccess(permission, _workContextAccessor.GetContext().CurrentUser, content)) return true; if (message != null) { - if (CurrentUser == null) { + if (_workContextAccessor.GetContext().CurrentUser == null) { _notifier.Error(T("{0}. Anonymous users do not have {1} permission.", message, permission.Name)); } else { _notifier.Error(T("{0}. Current user, {2}, does not have {1} permission.", - message, permission.Name, CurrentUser.UserName)); + message, permission.Name, _workContextAccessor.GetContext().CurrentUser.UserName)); } } diff --git a/src/Orchard/Security/SecurityModule.cs b/src/Orchard/Security/SecurityModule.cs deleted file mode 100644 index 33c3b57c1..000000000 --- a/src/Orchard/Security/SecurityModule.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Reflection; -using Autofac.Core; -using Castle.Core.Interceptor; -using Orchard.Environment.AutofacUtil.DynamicProxy2; -using Module = Autofac.Module; - -namespace Orchard.Security { - public class SecurityModule : Module { - protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { - var implementationType = registration.Activator.LimitType; - var property = FindProperty(implementationType); - - if (property != null) { - registration.InterceptedBy(); - } - } - - private static PropertyInfo FindProperty(Type type) { - return type.GetProperty("CurrentUser", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - null, - typeof(IUser), - new Type[0], - null); - } - } - - public interface ISecurityModuleInterceptor : IInterceptor, IDependency { - - } - - public class SecurityModuleInterceptor : ISecurityModuleInterceptor { - private readonly IAuthenticationService _authenticationService; - - public SecurityModuleInterceptor(IAuthenticationService authenticationService) { - _authenticationService = authenticationService; - } - - public void Intercept(IInvocation invocation) { - if (invocation.Method.ReturnType == typeof(IUser) && invocation.Method.Name == "get_CurrentUser") { - invocation.ReturnValue = _authenticationService.GetAuthenticatedUser(); - } - else { - invocation.Proceed(); - } - } - } -} diff --git a/src/Orchard/Services/Clock.cs b/src/Orchard/Services/Clock.cs index 6e1b5a38b..e72f7fae1 100644 --- a/src/Orchard/Services/Clock.cs +++ b/src/Orchard/Services/Clock.cs @@ -4,6 +4,16 @@ using Orchard.Caching; namespace Orchard.Services { public interface IClock : IVolatileProvider { DateTime UtcNow { get; } + + /// + /// Each retrieved value is cached during the specified amount of time. + /// + IVolatileToken When(TimeSpan duration); + + /// + /// The cache is active until the specified time. Each subsequent access won't be cached. + /// + IVolatileToken WhenUtc(DateTime absoluteUtc); } public class Clock : IClock { @@ -11,5 +21,33 @@ namespace Orchard.Services { get { return DateTime.UtcNow; } } + public IVolatileToken When(TimeSpan duration) { + return new AbsoluteExpirationToken(this, duration); + } + + public IVolatileToken WhenUtc(DateTime absoluteUtc) { + return new AbsoluteExpirationToken(this, absoluteUtc); + } + + public class AbsoluteExpirationToken : IVolatileToken { + private readonly IClock _clock; + private readonly DateTime _invalidateUtc; + + public AbsoluteExpirationToken(IClock clock, DateTime invalidateUtc) { + _clock = clock; + _invalidateUtc = invalidateUtc; + } + + public AbsoluteExpirationToken(IClock clock, TimeSpan duration) { + _clock = clock; + _invalidateUtc = _clock.UtcNow.Add(duration); + } + + public bool IsCurrent { + get { + return _clock.UtcNow < _invalidateUtc; + } + } + } } } diff --git a/src/Orchard/Settings/SettingsModule.cs b/src/Orchard/Settings/SettingsModule.cs deleted file mode 100644 index d77d3b820..000000000 --- a/src/Orchard/Settings/SettingsModule.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Reflection; -using Autofac.Core; -using Castle.Core.Interceptor; -using Orchard.Environment.AutofacUtil.DynamicProxy2; -using Module = Autofac.Module; - -namespace Orchard.Settings { - public class SettingsModule : Module { - protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { - var implementationType = registration.Activator.LimitType; - var property = FindProperty(implementationType); - - if (property != null) { - registration.InterceptedBy(); - } - } - - private static PropertyInfo FindProperty(Type type) { - return type.GetProperty("CurrentSite", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - null, - typeof(ISite), - new Type[0], - null); - } - } - - public interface ISettingsModuleInterceptor : IInterceptor, IDependency { - - } - - public class SettingsModuleInterceptor : ISettingsModuleInterceptor { - private readonly ISiteService _siteService; - - public SettingsModuleInterceptor(ISiteService siteService) { - _siteService = siteService; - } - - public void Intercept(IInvocation invocation) { - if (invocation.Method.ReturnType == typeof(ISite) && invocation.Method.Name == "get_CurrentSite") { - invocation.ReturnValue = _siteService.GetSiteSettings(); - } - else { - invocation.Proceed(); - } - } - } -} diff --git a/src/Orchard/Themes/ExtensionManagerExtensions.cs b/src/Orchard/Themes/ExtensionManagerExtensions.cs deleted file mode 100644 index 7de3840b0..000000000 --- a/src/Orchard/Themes/ExtensionManagerExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.IO; -using System.Linq; -using Orchard.Environment.Extensions; -using Orchard.Environment.Extensions.Models; - -namespace Orchard.Themes { - public static class ExtensionManagerExtensions { - public static ExtensionDescriptor GetExtensionDescriptor(this IExtensionManager extensionManager, string extensionType, string extensionName) { - return - extensionManager.AvailableExtensions().FirstOrDefault( - ed => ed.ExtensionType == extensionType && ed.Name == extensionName); - } - - public static string GetThemeLocation(this IExtensionManager extensionManager, ITheme theme) { - ExtensionDescriptor descriptor = extensionManager.GetExtensionDescriptor("Theme", theme.ThemeName); - - return descriptor != null ? Path.Combine(descriptor.Location, descriptor.Name) : "~"; - } - } -} \ No newline at end of file diff --git a/src/Orchard/Themes/ITheme.cs b/src/Orchard/Themes/ITheme.cs deleted file mode 100644 index e7e53ce86..000000000 --- a/src/Orchard/Themes/ITheme.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Orchard.Themes { - /// - /// Interface provided by the "themes" model. - /// - public interface ITheme { - bool Enabled { get; set; } - string ThemeName { get; set; } - string DisplayName { get; set; } - string Description { get; set; } - string Version { get; set; } - string Author { get; set; } - string HomePage { get; set; } - string Tags { get; set; } - string Zones { get; set; } - string BaseTheme { get; set; } - } -} diff --git a/src/Orchard/Themes/IThemeManager.cs b/src/Orchard/Themes/IThemeManager.cs new file mode 100644 index 000000000..40f37ccf4 --- /dev/null +++ b/src/Orchard/Themes/IThemeManager.cs @@ -0,0 +1,9 @@ +using System; +using System.Web.Routing; +using Orchard.Environment.Extensions.Models; + +namespace Orchard.Themes { + public interface IThemeManager : IDependency { + ExtensionDescriptor GetRequestTheme(RequestContext requestContext); + } +} diff --git a/src/Orchard/Themes/IThemeService.cs b/src/Orchard/Themes/IThemeService.cs deleted file mode 100644 index 53e819c5d..000000000 --- a/src/Orchard/Themes/IThemeService.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Web; -using System.Web.Routing; - -namespace Orchard.Themes { - public interface IThemeService : IDependency { - ITheme GetThemeByName(string themeName); - - ITheme GetSiteTheme(); - void SetSiteTheme(string themeName); - ITheme GetRequestTheme(RequestContext requestContext); - - void EnableTheme(string themeName); - void DisableTheme(string themeName); - - IEnumerable GetInstalledThemes(); - IEnumerable GetEnabledThemes(); - void InstallTheme(HttpPostedFileBase file); - void UninstallTheme(string themeName); - } -} diff --git a/src/Orchard/Themes/ThemeManager.cs b/src/Orchard/Themes/ThemeManager.cs new file mode 100644 index 000000000..21dd709a8 --- /dev/null +++ b/src/Orchard/Themes/ThemeManager.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using System.Web.Routing; +using Orchard.Environment.Extensions; +using Orchard.Environment.Extensions.Models; + +namespace Orchard.Themes { + public class ThemeManager : IThemeManager { + private readonly IEnumerable _themeSelectors; + private readonly IExtensionManager _extensionManager; + + public ThemeManager(IEnumerable themeSelectors, + IExtensionManager extensionManager) { + _themeSelectors = themeSelectors; + _extensionManager = extensionManager; + } + + public ExtensionDescriptor GetRequestTheme(RequestContext requestContext) { + var requestTheme = _themeSelectors + .Select(x => x.GetTheme(requestContext)) + .Where(x => x != null) + .OrderByDescending(x => x.Priority); + + if (requestTheme.Count() < 1) + return null; + + foreach (var theme in requestTheme) { + var t = _extensionManager.GetExtension(theme.ThemeName); + if (t != null) + return t; + } + + return _extensionManager.GetExtension("SafeMode"); + } + } +} \ No newline at end of file diff --git a/src/Orchard/Themes/ThemesModule.cs b/src/Orchard/Themes/ThemesModule.cs deleted file mode 100644 index e2d3ef45e..000000000 --- a/src/Orchard/Themes/ThemesModule.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Reflection; -using Autofac; -using Autofac.Core; -using Module = Autofac.Module; - -namespace Orchard.Themes { - public class ThemesModule : Module { - protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration) { - - var themeProperty = FindThemeProperty(registration.Activator.LimitType); - - if (themeProperty != null) { - registration.Activated += (sender, e) => { - var themeService = e.Context.Resolve(); - var currentTheme = themeService.GetSiteTheme(); - themeProperty.SetValue(e.Instance, currentTheme, null); - }; - } - } - - private static PropertyInfo FindThemeProperty(Type type) { - return type.GetProperty("CurrentTheme", typeof(ITheme)); - } - } -} diff --git a/src/Orchard/UI/Navigation/NavigationManager.cs b/src/Orchard/UI/Navigation/NavigationManager.cs index e5b998390..125225eb2 100644 --- a/src/Orchard/UI/Navigation/NavigationManager.cs +++ b/src/Orchard/UI/Navigation/NavigationManager.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Web.Mvc; using System.Web.Routing; -using JetBrains.Annotations; using Orchard.Security; using Orchard.Security.Permissions; @@ -11,15 +10,15 @@ namespace Orchard.UI.Navigation { private readonly IEnumerable _providers; private readonly IAuthorizationService _authorizationService; private readonly UrlHelper _urlHelper; + private readonly IOrchardServices _orchardServices; - public NavigationManager(IEnumerable providers, IAuthorizationService authorizationService, UrlHelper urlHelper) { + public NavigationManager(IEnumerable providers, IAuthorizationService authorizationService, UrlHelper urlHelper, IOrchardServices orchardServices) { _providers = providers; _authorizationService = authorizationService; _urlHelper = urlHelper; + _orchardServices = orchardServices; } - protected virtual IUser CurrentUser { get; [UsedImplicitly] private set; } - public IEnumerable BuildMenu(string menuName) { var sources = GetSources(menuName); return FinishMenu(Crop(Reduce(Merge(sources))).ToArray()); @@ -62,11 +61,11 @@ namespace Orchard.UI.Navigation { } private IEnumerable Reduce(IEnumerable items) { - var hasDebugShowAllMenuItems = _authorizationService.TryCheckAccess(Permission.Named("DebugShowAllMenuItems"), CurrentUser, null); + var hasDebugShowAllMenuItems = _authorizationService.TryCheckAccess(Permission.Named("DebugShowAllMenuItems"), _orchardServices.WorkContext.CurrentUser, null); foreach (var item in items) { if (hasDebugShowAllMenuItems || !item.Permissions.Any() || - item.Permissions.Any(x => _authorizationService.TryCheckAccess(x, CurrentUser, null))) { + item.Permissions.Any(x => _authorizationService.TryCheckAccess(x, _orchardServices.WorkContext.CurrentUser, null))) { yield return new MenuItem { Items = Reduce(item.Items), Permissions = item.Permissions, diff --git a/src/Orchard/UI/Resources/ResourceManager.cs b/src/Orchard/UI/Resources/ResourceManager.cs index 6093521e5..08f961d86 100644 --- a/src/Orchard/UI/Resources/ResourceManager.cs +++ b/src/Orchard/UI/Resources/ResourceManager.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Web; using Autofac.Features.Metadata; using Orchard.DisplayManagement.Descriptors; +using Orchard.Environment.Extensions.Models; namespace Orchard.UI.Resources { public class ResourceManager : IResourceManager { @@ -14,7 +15,7 @@ namespace Orchard.UI.Resources { private readonly List _links = new List(); private readonly Dictionary _metas = new Dictionary(); private readonly Dictionary> _builtResources = new Dictionary>(StringComparer.OrdinalIgnoreCase); - private readonly IEnumerable> _providers; + private readonly IEnumerable> _providers; private ResourceManifest _dynamicManifest; private List _headScripts; private List _footScripts; @@ -31,7 +32,7 @@ namespace Orchard.UI.Resources { return resourcePath; } - public ResourceManager(IEnumerable> resourceProviders) { + public ResourceManager(IEnumerable> resourceProviders) { _providers = resourceProviders; } @@ -40,7 +41,9 @@ namespace Orchard.UI.Resources { if (_manifests == null) { var builder = new ResourceManifestBuilder(); foreach (var provider in _providers) { - builder.Feature = provider.Metadata.Feature; + builder.Feature = provider.Metadata.ContainsKey("Feature") ? + (Feature) provider.Metadata["Feature"] : + null; provider.Value.BuildManifests(builder); } _manifests = builder.ResourceManifests; diff --git a/src/Orchard/WorkContext.cs b/src/Orchard/WorkContext.cs index abb4255a0..5cecd7dbf 100644 --- a/src/Orchard/WorkContext.cs +++ b/src/Orchard/WorkContext.cs @@ -1,4 +1,5 @@ using System.Web; +using Orchard.Environment.Extensions.Models; using Orchard.Security; using Orchard.Settings; using Orchard.Themes; @@ -31,10 +32,9 @@ namespace Orchard { set { SetState("CurrentUser", value); } } - public ITheme CurrentTheme { - get { return GetState("CurrentTheme"); } + public ExtensionDescriptor CurrentTheme { + get { return GetState("CurrentTheme"); } set { SetState("CurrentTheme", value); } } - } -} \ No newline at end of file +} diff --git a/src/Tools/PackageIndexReferenceImplementation/Controllers/FeedController.cs b/src/Tools/PackageIndexReferenceImplementation/Controllers/FeedController.cs index 06d6ef74b..9bcdaf383 100644 --- a/src/Tools/PackageIndexReferenceImplementation/Controllers/FeedController.cs +++ b/src/Tools/PackageIndexReferenceImplementation/Controllers/FeedController.cs @@ -16,6 +16,9 @@ using PackageIndexReferenceImplementation.Services; namespace PackageIndexReferenceImplementation.Controllers { [HandleError] public class FeedController : Controller { + private const string VersionTag = "Version"; + private const string ExtensionsNamespace = "http://orchardproject.net"; + private readonly FeedStorage _feedStorage; private readonly MediaStorage _mediaStorage; @@ -104,7 +107,12 @@ namespace PackageIndexReferenceImplementation.Controllers { } if ( !string.IsNullOrEmpty(packageProperties.Version) ) { - item.ElementExtensions.Add("Version", "http://orchardproject.net", packageProperties.Version); + var versionExtensions = item.ElementExtensions.Where(e => e.OuterName == VersionTag && e.OuterNamespace == ExtensionsNamespace); + foreach(var versionExtension in versionExtensions) { + item.ElementExtensions.Remove(versionExtension); + } + + item.ElementExtensions.Add(VersionTag, ExtensionsNamespace, packageProperties.Version); } var mediaIdentifier = packageProperties.Identifier + "-" + packageProperties.Version + ".zip";