Compare commits
1320 Commits
release-6.0.4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 4935525591 | |||
| 693778fe74 | |||
| 8eee7cae2f | |||
| 226e35d65a | |||
| cdda69c4cd | |||
| 0cff484113 | |||
| 830fde372e | |||
| 35f65a2c64 | |||
| e5320f0abd | |||
| 965a7fc500 | |||
| abbf8aeb42 | |||
| 328ada2f38 | |||
| 767252cdf1 | |||
| 010d47c68b | |||
| a353f6fb74 | |||
| a64efb93b3 | |||
| cf9f11ff45 | |||
| d7481b5ca4 | |||
| 2fb55cb831 | |||
| 0e6a926a3f | |||
| 173ac65eb5 | |||
| 7c28e1aeba | |||
| 5989d19f7f | |||
| da1c33a034 | |||
| 2111a5e31e | |||
| 5478de911b | |||
| 7765acb130 | |||
| 5640daff32 | |||
| a1cae3f286 | |||
| d22dbb4654 | |||
| 4d5a8298b0 | |||
| 9e2733ce69 | |||
| fbfdd8d398 | |||
| 2552dffdad | |||
| 52540165f1 | |||
| 2b408df24c | |||
| d559411187 | |||
| 3a4a6579d3 | |||
| 1e76cf67d3 | |||
| 61149f8112 | |||
| adb059e0da | |||
| 4337976887 | |||
| efe5de87a6 | |||
| 389642946e | |||
| 53d30aa3cb | |||
| e233cffb9d | |||
| 9e58ebed24 | |||
| f51c4e332e | |||
| 03a0a0a0e9 | |||
| dcb381770f | |||
| 65db0e69a9 | |||
| 23c6a91e9c | |||
| a03c6dcf13 | |||
| 3029d97f33 | |||
| f41d967864 | |||
| 4a481b05d4 | |||
| 66c6b5b524 | |||
| e3b0f71549 | |||
| 973b466798 | |||
| fa0eef4333 | |||
| a343a76a26 | |||
| d0a9e3236e | |||
| b899805ec9 | |||
| 766497e355 | |||
| 67a2a9cfe4 | |||
| 766ba0c8f5 | |||
| ca71c59880 | |||
| 6c87cf729a | |||
| 5c63afa31a | |||
| fa88768c91 | |||
| bfabfd9fa5 | |||
| aa1c411c8c | |||
| c52c452b36 | |||
| 86811fe507 | |||
| 363de53b82 | |||
| 958fb66f2c | |||
| 30e12c1367 | |||
| 89ff7d85e2 | |||
| 61fbf2cfc6 | |||
| ce847e97a8 | |||
| 1e61563f79 | |||
| b4f9985695 | |||
| 82f19ede8c | |||
| 0fbc32a87f | |||
| dc2de4b5e7 | |||
| 5fce741940 | |||
| 14e4a8061c | |||
| 1b9f071581 | |||
| 79141ef86d | |||
| 08609a887c | |||
| b11932240c | |||
| d47b4517c1 | |||
| 226a13c6e1 | |||
| d78a03a610 | |||
| b7a1123319 | |||
| 7e9cad34db | |||
| c4b44ea0e3 | |||
| 3435a75e9e | |||
| bdb6c5768a | |||
| 87a3c53e22 | |||
| 898d25f3cb | |||
| 9bc3fdd555 | |||
| cbda86fe92 | |||
| b48f0f52e0 | |||
| e2eeafcbfc | |||
| ad697db42b | |||
| 9bb31e9456 | |||
| a195d33332 | |||
| 82a87cbd92 | |||
| 5b26436862 | |||
| eed61f9053 | |||
| 55c68485e9 | |||
| b9ba350a2f | |||
| 696306e7c9 | |||
| 9bf86aff09 | |||
| f50de5b049 | |||
| d734ba6136 | |||
| c49becea53 | |||
| 614aea203d | |||
| ed88bbf75f | |||
| e41d3c7e84 | |||
| a099af39c2 | |||
| 118f9b02e2 | |||
| 38778cc7c7 | |||
| ffff9efaa8 | |||
| 7f4abb4893 | |||
| 4d39ce1202 | |||
| 7164f23a98 | |||
| 8b2d1b8eab | |||
| 80394f08fb | |||
| ca1fe5ff2a | |||
| a1037ce43c | |||
| 2cd2f3741d | |||
| e634dba4ea | |||
| d1eb8fd9eb | |||
| 2e91c89c02 | |||
| 8be54ba0cc | |||
| 3da7682415 | |||
| 775892ff5a | |||
| f30b4c8184 | |||
| 319ba5c791 | |||
| 398bc6d767 | |||
| 5d3ef8d97f | |||
| 08a300fbe5 | |||
| 845770c4bb | |||
| 771dc10c85 | |||
| 2ac76202e5 | |||
| a5ecbe96e2 | |||
| 7240b22e48 | |||
| 1f00589cb4 | |||
| 60b14487a9 | |||
| 33bc85a843 | |||
| e6642674d4 | |||
| 8ad5fb3c44 | |||
| 1752d14c57 | |||
| ec4ccba1a7 | |||
| 0244492a89 | |||
| 546cf2c84d | |||
| d354dde774 | |||
| 22c9e9acd9 | |||
| 5dd14723e9 | |||
| 7134e80c44 | |||
| f7196ee8f9 | |||
| fdecd697b7 | |||
| 6c03dac869 | |||
| 6cdb564a9f | |||
| 0da8a8db36 | |||
| a4a9620889 | |||
| 2307424fb6 | |||
| ca124fb662 | |||
| 6787252f9b | |||
| ef3094f8d9 | |||
| a2a20133aa | |||
| bb750d186a | |||
| f2a7dde5ce | |||
| 73e2559a13 | |||
| 80f8a9d01c | |||
| 6f9883d373 | |||
| 41c920a4ec | |||
| 1f79b71738 | |||
| 64fb588556 | |||
| 90cfd004cb | |||
| b5494546c7 | |||
| 7bac1ef1cd | |||
| ad927ec6c1 | |||
| 8a19d28859 | |||
| 7e24af9daf | |||
| 7518b514a7 | |||
| da15d40b04 | |||
| 96c38f50e4 | |||
| e723f1169f | |||
| 914005b2b6 | |||
| 67bd303173 | |||
| 972b903f52 | |||
| 20e6843bf0 | |||
| 61d072c8d6 | |||
| 8740848aac | |||
| 85c80b07f9 | |||
| 6766aa9732 | |||
| 557dccd88b | |||
| a57334d1f7 | |||
| 334f0bfd2b | |||
| 3dea16fad1 | |||
| 1bf4121796 | |||
| 93bebdd50b | |||
| 6a9532f10a | |||
| 986d37afd6 | |||
| d88494e90e | |||
| e48f08b657 | |||
| a79e349f3d | |||
| 1c70570078 | |||
| 197dacfae7 | |||
| d8aad718d5 | |||
| 1d7bfc2781 | |||
| 8063717e4c | |||
| 3900b7ebc8 | |||
| 0296c646cb | |||
| 275dbc83dd | |||
| 1cd2dc8a42 | |||
| 60867af1a7 | |||
| 1e129bcc4d | |||
| e5c758bbc1 | |||
| 25780663a6 | |||
| 63ea79a4d6 | |||
| aa327696fe | |||
| 1272a7c74b | |||
| dcbe6726b0 | |||
| ba68da5736 | |||
| fdabd945dc | |||
| 868edee5e6 | |||
| b91d0bb117 | |||
| cc91977e94 | |||
| 90b94f6ffb | |||
| 3c4cf56309 | |||
| b7f6195791 | |||
| 42eb82e6ca | |||
| 93def731ef | |||
| 60805f91d6 | |||
| 048480d5be | |||
| 173d388c12 | |||
| b1285fa7e3 | |||
| e34c857f6c | |||
| 7ff0e6cd4b | |||
| 0683094f84 | |||
| 983b7a85e1 | |||
| d015780b9f | |||
| e4df176a37 | |||
| aeece499bb | |||
| 8465b4e556 | |||
| e280785f48 | |||
| 5e0a59e4b3 | |||
| 30835797ff | |||
| 4077a01a6b | |||
| aed70ae40c | |||
| 6d44628352 | |||
| 7a398d34b1 | |||
| 69c5aeb1b3 | |||
| da545b890b | |||
| 6609bc09f2 | |||
| f06a6f42da | |||
| c9065d96a9 | |||
| 9d4e1362c4 | |||
| d3b69e04e1 | |||
| 0d54e8df89 | |||
| 8f949d0a2f | |||
| d67480e98b | |||
| 5d76ead469 | |||
| 2796100067 | |||
| a132f609d7 | |||
| 7f7456701d | |||
| d926180e3a | |||
| ffce1a3e6b | |||
| e553f2c671 | |||
| 42c6533e16 | |||
| b0f4cb7d02 | |||
| f809dec874 | |||
| 2477500045 | |||
| 72bb1b3583 | |||
| 240e58e061 | |||
| e980296d6d | |||
| d23482b7a6 | |||
| d89539a437 | |||
| 4368f15097 | |||
| b90150279b | |||
| ca1b05e30d | |||
| 5c09ba9a2d | |||
| cfa3e3aff1 | |||
| 59ff4a0484 | |||
| b1db99f639 | |||
| ccbb838cef | |||
| b12f60e443 | |||
| 0d5ec8bfd5 | |||
| 5f67e85471 | |||
| d9228c368f | |||
| 212800f706 | |||
| 8226505e5b | |||
| 41b8de09b7 | |||
| bbf06cd13d | |||
| 639cb17741 | |||
| 4643d34546 | |||
| 50035eae49 | |||
| 2d857a8635 | |||
| d47ff4005c | |||
| dfeb1c7a0b | |||
| e4387b8dae | |||
| 188aca499a | |||
| 3040d362ef | |||
| a57aa07721 | |||
| f2b8e3407b | |||
| 1ec7cd3b89 | |||
| bd77463fa4 | |||
| 368954226a | |||
| 496d51c2a0 | |||
| b01b4f7aa7 | |||
| 49a699c858 | |||
| f68571ef7c | |||
| 6cc1735363 | |||
| d553dfd4b0 | |||
| f3e737720b | |||
| 22cf59345c | |||
| 16a46a4ea4 | |||
| 09d9728fb8 | |||
| c0df3e0202 | |||
| d09e283900 | |||
| 507c6c23b9 | |||
| 3daf936623 | |||
| e93c910347 | |||
| 7139e30296 | |||
| df1940a01c | |||
| aafb5a0285 | |||
| 033f981718 | |||
| 5bd55bdd09 | |||
| 76358e3e13 | |||
| 35c0eb3b0c | |||
| 7fad8ca98b | |||
| a2da27121e | |||
| 23ec07276a | |||
| 96cec0b407 | |||
| 47b94e68e3 | |||
| 0f4b1752e0 | |||
| eac66f5696 | |||
| b2c604f7b3 | |||
| 3f626b444f | |||
| c5b8931aa6 | |||
| 818d22ba61 | |||
| f9902964b0 | |||
| 27fdb1ebab | |||
| 1368ba8dc9 | |||
| 9a3c2bbc5c | |||
| 0b0fb92cf1 | |||
| 6f09da0927 | |||
| febe6ec241 | |||
| 3618722574 | |||
| 24a76f53b4 | |||
| 86ce48ddc8 | |||
| cb592d687c | |||
| 2161ec98b0 | |||
| 5a6ee168c3 | |||
| 52292cab60 | |||
| 2933c879e1 | |||
| c8a19dff44 | |||
| a6768263d3 | |||
| e66306978a | |||
| 7f22809ebf | |||
| 302ebde422 | |||
| cf5624f377 | |||
| f386c9d024 | |||
| 530fcf0ea3 | |||
| 26e4091f28 | |||
| 32f86f750e | |||
| ebad631140 | |||
| b8304c03ee | |||
| 556c2d625f | |||
| 6f85eefd85 | |||
| aaa4469def | |||
| baa0069262 | |||
| 9ac4c7aef5 | |||
| cb2a35594f | |||
| dd501d0198 | |||
| b724d8fb32 | |||
| 7c6aee17e9 | |||
| 5e2c3a0a8b | |||
| f5121bd183 | |||
| 51b5334126 | |||
| 273c1956ab | |||
| f7c474ac2c | |||
| 4143dbd02d | |||
| 768eb3d1ed | |||
| 120bdca9eb | |||
| a5041aa34e | |||
| 59811c2841 | |||
| 38eee6135e | |||
| d3780848dc | |||
| 5719820fad | |||
| 9d15228c68 | |||
| c9c3623457 | |||
| aecc3d28bf | |||
| b51022575f | |||
| 6600e9c899 | |||
| 68aa2abbc0 | |||
| e0a483ca48 | |||
| 9b78cb3f7c | |||
| c6c90fde44 | |||
| 773500332b | |||
| 95eb00a81c | |||
| 3921b0974e | |||
| 2cd07c841f | |||
| 8f80f0e95c | |||
| 73ac2c0309 | |||
| a5ddb6c818 | |||
| 458e61e049 | |||
| 0815842640 | |||
| 53b31a5c1b | |||
| 292dd9115b | |||
| c6d0a9be00 | |||
| 14c3acc4b7 | |||
| a4098b5d25 | |||
| acdcca0b91 | |||
| 33ff82e766 | |||
| 5fd90e1c13 | |||
| a6eaec9ecb | |||
| f5553bcc06 | |||
| e0c68a8e1c | |||
| bc1b2dc5f4 | |||
| 0bb643672f | |||
| 813d60521c | |||
| 5212d17f49 | |||
| 932115585e | |||
| 948ffe4796 | |||
| 6b1dd07310 | |||
| dc2554c6d0 | |||
| 5c6514929e | |||
| 9739b3e2ef | |||
| 0b1f72f139 | |||
| 2a2e867784 | |||
| 79e0242468 | |||
| 242443d861 | |||
| 7c066b9ded | |||
| 159d605434 | |||
| 1971006a48 | |||
| 5c0c33a46b | |||
| 9bd255d9a5 | |||
| cc7f41d9ee | |||
| b4b0a37c2c | |||
| 8c841f97cc | |||
| a1ee352514 | |||
| c25b06b15f | |||
| 78bfb6a8cc | |||
| d8a8bf5f74 | |||
| b70c98ea74 | |||
| a8ad8c2a43 | |||
| 96f8cd3d60 | |||
| 91436ad247 | |||
| 678f911ff1 | |||
| afbe3ca3b9 | |||
| 32d6f2e50c | |||
| 9909f5b6be | |||
| ddbe15de08 | |||
| 5c5d63ce9a | |||
| d3916a1d85 | |||
| db7cb2dcb4 | |||
| 6281268954 | |||
| cd606a7e9e | |||
| ae9d77a765 | |||
| f6e44b4e7c | |||
| 8e1c45e981 | |||
| 955282f260 | |||
| 4a7ee52d63 | |||
| b4d88b0361 | |||
| b41cf37dd5 | |||
| e6fcdc8dc6 | |||
| 547a137b9a | |||
| 5041e6fcc4 | |||
| db0d139a39 | |||
| fc32100142 | |||
| 7ecbc3b391 | |||
| c3c44df52e | |||
| 13a86624ff | |||
| 2f61bc27c8 | |||
| f484dbf0fc | |||
| 6d0ededd9f | |||
| e7d157a209 | |||
| d3ed90c23e | |||
| f6155d8e49 | |||
| c1cd609325 | |||
| b916360771 | |||
| db4b93dbc3 | |||
| fa8934f89a | |||
| c6940096d3 | |||
| 40868ac361 | |||
| f399a9f52b | |||
| 562851b93e | |||
| 634e4a6949 | |||
| e61b567ee1 | |||
| 7ccae64dd1 | |||
| aef44065c5 | |||
| 4ce22b836e | |||
| 2b8544b4c7 | |||
| 6afa6a277f | |||
| f5bf05a6f5 | |||
| 469db82f1d | |||
| e50569597b | |||
| 071f3dcc01 | |||
| e0bc99af9c | |||
| 232581664b | |||
| b15e147d6b | |||
| c7a4c782e3 | |||
| 780908e24f | |||
| 3ac7e237c4 | |||
| 6943a454f3 | |||
| e870db3c29 | |||
| 41b17160f7 | |||
| b19621c07b | |||
| 0ff979e814 | |||
| f26e39f5ce | |||
| 9a6030a3eb | |||
| 84ef216d57 | |||
| ecfe51134d | |||
| c8414116ad | |||
| 532f407260 | |||
| 834d04f8ed | |||
| 2aa902beaf | |||
| 2f16e6662d | |||
| 0c4897d7c1 | |||
| 43dc14fa93 | |||
| e209aa3c2a | |||
| 5890fe1849 | |||
| b6f52bf782 | |||
| 922ebe5411 | |||
| f36ab37f6a | |||
| aeff33d0a6 | |||
| 645637d550 | |||
| 5cfe9e57ce | |||
| 4863e657df | |||
| 2486e75210 | |||
| c0e1be4df9 | |||
| a93e562f14 | |||
| 2201c644f7 | |||
| 822cac5d87 | |||
| d58487fafc | |||
| ea9653fa83 | |||
| b38397868e | |||
| 7d1a18638b | |||
| 748e88c3e8 | |||
| cb8d080f1d | |||
| 3fd3bf0fda | |||
| 09a6cdc8b6 | |||
| b2fe35695f | |||
| 67b57dea50 | |||
| 3d6172738f | |||
| a43e0eb5b8 | |||
| 3b05663597 | |||
| 191d744ec6 | |||
| 980cd20e4c | |||
| f04916c9a9 | |||
| 8fde65d417 | |||
| 8cca1b77b3 | |||
| 53e4308c29 | |||
| d10eff04a7 | |||
| 59c36ad70e | |||
| 7b8d526a8a | |||
| f69a017078 | |||
| 6f26f7b57c | |||
| bda2614290 | |||
| efc482511e | |||
| 40b90b8a58 | |||
| a009dfe2a1 | |||
| bc0b419288 | |||
| 806715594e | |||
| 41e87fca98 | |||
| f23c6c53cc | |||
| f2a97326fa | |||
| dd1983dc55 | |||
| 78cd51d333 | |||
| 28b6c5897f | |||
| baed852767 | |||
| 0762decd92 | |||
| 0b58c1c03c | |||
| 38c6a21896 | |||
| 15bff44ec1 | |||
| a626efa9b6 | |||
| 1f87470f89 | |||
| 54d2258634 | |||
| 25be0621b2 | |||
| 6fe3507099 | |||
| cba09ed817 | |||
| d5d00553b4 | |||
| d94772892d | |||
| 55750b534b | |||
| a31cb3b1df | |||
| fc44138d9e | |||
| 0cda994538 | |||
| 4b199a9166 | |||
| cfe6ac0486 | |||
| c52669fb05 | |||
| 753fe411c5 | |||
| 50c12a5c35 | |||
| b42fb1c5c1 | |||
| f05c77dc78 | |||
| d1677d9d59 | |||
| 137685d883 | |||
| 266d8ba69a | |||
| c4a071523e | |||
| ca99319ead | |||
| f808aac4cd | |||
| 0553bd1f9f | |||
| 81360f629e | |||
| 1b3669787b | |||
| aa36c66f39 | |||
| 950cb1436a | |||
| 09e31d6595 | |||
| f9fc2619fa | |||
| 004d9ab3e6 | |||
| 5d8cfa5efb | |||
| 297f8e2a0b | |||
| 83584375c1 | |||
| 8ddfb5f6ad | |||
| 9387544865 | |||
| 66ddb21ef8 | |||
| d746ec6409 | |||
| e08322f6fe | |||
| de52f3ee93 | |||
| 9d19ed9463 | |||
| df62697477 | |||
| f0cacf0d52 | |||
| d501fcb679 | |||
| 3c15f9b57c | |||
| f5994d8442 | |||
| bfe5250138 | |||
| 3fa9219c27 | |||
| 4295cba915 | |||
| 6d66fc6cb8 | |||
| 4484f83caa | |||
| 3ada1770eb | |||
| cbf84566e2 | |||
| 294c2f4fba | |||
| 0b6f05e630 | |||
| 2170380f7b | |||
| a8ab7e4c35 | |||
| c20c9c638f | |||
| 43b2a2185e | |||
| 2423bdd623 | |||
| bcb90d64a5 | |||
| eca01b845c | |||
| dc5cf5ef6e | |||
| 7d448d0959 | |||
| 53fe02db7e | |||
| af51465a6a | |||
| b2929ea50a | |||
| a03dd7b11e | |||
| 6d994f48ac | |||
| 8e1f7170c7 | |||
| 3fd1c49da7 | |||
| f0e8252e38 | |||
| ad06aded1b | |||
| be049f9093 | |||
| 64bbfb8cbc | |||
| 0ca52fcc60 | |||
| c53342ba4c | |||
| 25eea8d599 | |||
| 22498649b1 | |||
| 25ce7baa7d | |||
| b4fd2f6d46 | |||
| aba4a9b07c | |||
| 577d77cfab | |||
| 7ff50e2652 | |||
| e885384678 | |||
| 528209f8da | |||
| 056696d36f | |||
| 6cffa67518 | |||
| d2a285c120 | |||
| 153fe248a7 | |||
| 7fc4822bbe | |||
| d65bee76b2 | |||
| 385d6396b0 | |||
| 46858af1ed | |||
| 34163625fe | |||
| c2057656bc | |||
| 09a4e33f3f | |||
| e53b388a5e | |||
| 4fb4af0b4f | |||
| 461f032777 | |||
| ab37f9ae35 | |||
| a3347c0037 | |||
| f3835d1ca3 | |||
| d30c4791fe | |||
| 7ee9b9ebcc | |||
| b4caf109f7 | |||
| 0e8ffe528a | |||
| a8029d1dc5 | |||
| a1d5b61ae5 | |||
| 6818ac4e50 | |||
| 710c8aa6ea | |||
| f8652d98fe | |||
| 174ff44e3b | |||
| b3c3e114ad | |||
| 60481e7e02 | |||
| 12de5d6ed3 | |||
| 7f5457316a | |||
| 671c8715b0 | |||
| d6d630cb2c | |||
| 988940095c | |||
| 08a049594c | |||
| a895a2a20a | |||
| a5e33e1e02 | |||
| a721f06ac8 | |||
| 39095b524c | |||
| 3b1bfe04f2 | |||
| 979fe46e9b | |||
| 0107a10145 | |||
| a38f0af49b | |||
| c12f9d0272 | |||
| 83d1e9c76f | |||
| b40619634d | |||
| fc84a21f06 | |||
| 9137ce7cf4 | |||
| 9621403f79 | |||
| 2245c88396 | |||
| 2e39c55d56 | |||
| e4e0bcf642 | |||
| 7537e4c6d6 | |||
| c410b6dc20 | |||
| 1e7e670df3 | |||
| da53ffe9f2 | |||
| 47f6401fcd | |||
| 33190ea5e1 | |||
| a06951afbd | |||
| 43d6c9a46d | |||
| 0b3eaf9c77 | |||
| 0fe8ff57a1 | |||
| 2642d74450 | |||
| 761b749f37 | |||
| 4ef9dbb9b4 | |||
| f716ba380c | |||
| 439445aae4 | |||
| 0d79eaf3c5 | |||
| e747438a4b | |||
| 14f71c9059 | |||
| 5154bcd2e9 | |||
| e3af8b4e5f | |||
| 3e8c1a426c | |||
| d7081dbc6b | |||
| 1d89702c2c | |||
| df26090d63 | |||
| 3050258fdc | |||
| 84e990c239 | |||
| 911a1cf80b | |||
| ef493ef9af | |||
| 76a12f3f33 | |||
| 344a4cc485 | |||
| 5e1115218c | |||
| 71a28cbeaa | |||
| 4aa750694a | |||
| 5d89ab1e2a | |||
| 262aa3b8fe | |||
| 106d733d08 | |||
| a010448ad1 | |||
| 111df761aa | |||
| 5f9c7bb49c | |||
| 0c3b7c27a7 | |||
| f2293e01fa | |||
| 506d32f353 | |||
| 16746c8548 | |||
| fb994bdc11 | |||
| abee79ca69 | |||
| d8ccf20840 | |||
| 9e10694ebb | |||
| 1c5cd4e245 | |||
| 63cae70ec3 | |||
| dd990b5df4 | |||
| d2d1843e03 | |||
| efbc461da9 | |||
| 97d41f8998 | |||
| 8ef88dc955 | |||
| e50bac7c9f | |||
| 01bf0bcfa5 | |||
| 7dcfcaf339 | |||
| 6badfae849 | |||
| 9d0dbda3bd | |||
| df986c8254 | |||
| cd823db766 | |||
| 2f9de56968 | |||
| 49a61c5820 | |||
| 2dfdc1050b | |||
| 9e239f135d | |||
| 480b84a223 | |||
| 635ebcb9be | |||
| 33f7a8477d | |||
| 646194e013 | |||
| 425fcf36eb | |||
| 31fd05ebca | |||
| 495b4ed9e0 | |||
| e1c810c033 | |||
| 87c904cc96 | |||
| 03c65c8eec | |||
| 14aeb55c14 | |||
| 7ddbc83731 | |||
| 17533c57d3 | |||
| 433668e202 | |||
| 9edcc0c903 | |||
| 7a1e3b96b8 | |||
| f747f69c62 | |||
| e07985439a | |||
| 620f21d7d7 | |||
| 4a13047d5d | |||
| 446a480f21 | |||
| b56f8c8fb3 | |||
| 296c24f829 | |||
| c5e88ef69f | |||
| 2a7e493c74 | |||
| e14d3fd379 | |||
| fa43cfd58f | |||
| 711afe8bb7 | |||
| 4abb9fff3e | |||
| 23525300bb | |||
| 2490908401 | |||
| b93ea7c69b | |||
| 640be73a66 | |||
| 32ae88fc81 | |||
| a4c9c3bfd9 | |||
| 182107286c | |||
| a7e939e71f | |||
| 4217949719 | |||
| 83d05bd01c | |||
| fc68ba69e2 | |||
| 9fb10ea004 | |||
| c916df0d13 | |||
| 28892a7bb2 | |||
| 99a63a3cdb | |||
| 65cb6fbaff | |||
| 4b49f9779f | |||
| c5b6bb52e0 | |||
| efee4d0c0c | |||
| b89951dd11 | |||
| 70ad3edc1f | |||
| 8d33488923 | |||
| 32a6a49077 | |||
| ad52c0f033 | |||
| 9982a09826 | |||
| 83308c3d5f | |||
| 495b661263 | |||
| f2d7e3549d | |||
| 4201d678fa | |||
| ff6ee360da | |||
| 1f999d7e22 | |||
| be24075850 | |||
| 6d18d32356 | |||
| 75f0f1f4ee | |||
| 425a9f6a34 | |||
| 1d5f7ae822 | |||
| 3f7a93e0c9 | |||
| 72ad9f51c1 | |||
| 20fb27f7e1 | |||
| c8e20cf64b | |||
| a89a122b09 | |||
| 3accecd504 | |||
| d9121b4684 | |||
| 132ec1702c | |||
| a4e3127704 | |||
| 2678e23c7d | |||
| 6148d63b02 | |||
| 4dc94d1e0b | |||
| b058b1e345 | |||
| dfa1e73ddf | |||
| 390f56a64d | |||
| 04c623f19c | |||
| 633d88c8c4 | |||
| 3ed4da19c2 | |||
| 40a9da5ee0 | |||
| 3b982b80f5 | |||
| 1cada5aeb5 | |||
| 64719586dc | |||
| 63d010f78f | |||
| e97a01c75c | |||
| a9df92b7a3 | |||
| 65ae43918d | |||
| 6e4d8b638e | |||
| 21c635f61a | |||
| 6cc747bf76 | |||
| af2693af76 | |||
| d95fc0210e | |||
| 00de509478 | |||
| 1b5139889c | |||
| d976fbe4de | |||
| 47474d31d6 | |||
| 840a95ba62 | |||
| e18d8da872 | |||
| b6ec364156 | |||
| 6b07ee83eb | |||
| 7e0c1fac36 | |||
| 8cdfba42d5 | |||
| e8dd56786b | |||
| 2a9309ea38 | |||
| c732ee6eb2 | |||
| ee2f2dfda0 | |||
| 9d6b38a1c1 | |||
| f6490a897a | |||
| ce8f5c167c | |||
| 5f242aa3f6 | |||
| ab8b0f4ebb | |||
| a57d3f7eba | |||
| f5a1e41569 | |||
| 8c79977a23 | |||
| 52f05612ad | |||
| c5a0da6aa5 | |||
| 266aa3423b | |||
| 7ea87638f7 | |||
| b96b372400 | |||
| fcb8f0d417 | |||
| 6e3c4854b9 | |||
| ba24deffc9 | |||
| aa7fd7bb2b | |||
| e7a6a29e59 | |||
| c43efbbfc4 | |||
| adedc9b64b | |||
| 73d77083ae | |||
| b2a1f67fb4 | |||
| 3a0d617b14 | |||
| ce0c72d9f8 | |||
| cb966ac70b | |||
| 6c40f32c2a | |||
| cce32f406f | |||
| 610ff91a9d | |||
| 45f39158ba | |||
| d7b5d73e62 | |||
| 780a9632f0 | |||
| 603b6c73f7 | |||
| 1b66c42c9b | |||
| 5175fb5188 | |||
| b260769799 | |||
| 4495fd05c4 | |||
| 923653f2b5 | |||
| 083320002b | |||
| 3052c7311f | |||
| 3af7958940 | |||
| c7498cec03 | |||
| abe4ec6524 | |||
| e3a8b4ac78 | |||
| 365dffe2db | |||
| 381157ac5d | |||
| f993e96547 | |||
| 734f75b3ad | |||
| 7ef066f396 | |||
| 23bb0e3ac3 | |||
| 2dea4a1d70 | |||
| 07bdd138cc | |||
| 2b750843c5 | |||
| bd81507ecb | |||
| ea7fb32fb9 | |||
| 2cd64dd540 | |||
| 2a058cdbcc | |||
| 37860b4015 | |||
| 0f056b1702 | |||
| aa5588bbd3 | |||
| 33c5c41a31 | |||
| 8d3c798c6c | |||
| 245591c31f | |||
| 8fb8fc00b4 | |||
| 50b05d25f5 | |||
| c04ee7bdc7 | |||
| 75d218d2e3 | |||
| 4efa2c9f57 | |||
| 630a44358f | |||
| f7015d521b | |||
| 860c8c1002 | |||
| a2120d1c6b | |||
| fc3f9dfeae | |||
| cf64c0243c | |||
| ca9f53738b | |||
| 8d2e466e34 | |||
| ec46d65bb4 | |||
| 164f22aa50 | |||
| cc50003e3e | |||
| 8698deb469 | |||
| 738e4f5c46 | |||
| c854ea8a35 | |||
| 9bd865d259 | |||
| 2d55dda662 | |||
| 29b2458ef3 | |||
| 1e6de161e6 | |||
| 508886b1ad | |||
| 3ab0879a99 | |||
| 4baecfe833 | |||
| e5e22f75fc | |||
| 3612f18f3f | |||
| 86852f9815 | |||
| 9aa44c40ce | |||
| da331b7408 | |||
| 0230bedeb6 | |||
| bd6aa51397 | |||
| 9b85bc0e64 | |||
| 2044d1b5db | |||
| 2c05eda899 | |||
| 0852200861 | |||
| f955955ad8 | |||
| 9042a23de7 | |||
| b9eaaa0f29 | |||
| f79d046a87 | |||
| 737d7d6712 | |||
| 4d8ed22206 | |||
| 06dc76496d | |||
| 2877b7bda4 | |||
| c137854e01 | |||
| fe9f5b224a | |||
| 45f2cc9a20 | |||
| f1c680c7e2 | |||
| 36108df4d0 | |||
| 51ad21302a | |||
| 010893a73a | |||
| 97f3f13aaa | |||
| 32e6604cf7 | |||
| b2cedf6380 | |||
| 9fc5ee897f | |||
| e8e8053063 | |||
| c635ec67d0 | |||
| 750370d148 | |||
| 2c6daa2918 | |||
| e33c877605 | |||
| cab21e9d48 | |||
| 2e7c26fcc0 | |||
| 0f6c41679c | |||
| 85e73df3c8 | |||
| a17a11d50b | |||
| 6ead98a51d | |||
| 7cc12211e1 | |||
| f9b7e1b7fa | |||
| 33c5f3fcc7 | |||
| 47f6924ac3 | |||
| 45b8daa18c | |||
| 1157c11d89 | |||
| 6815092b62 | |||
| 876753cb54 | |||
| b374dcf2c2 | |||
| f7cfa507d7 | |||
| 5df0013406 | |||
| 30d08bfae1 | |||
| b0ae03b220 | |||
| ffb9849745 | |||
| cc55107da3 | |||
| 6c4ee40b96 | |||
| c637c517b8 | |||
| cdf6249a41 | |||
| d9540bcfc5 | |||
| aeb417d3d8 | |||
| bcfc7b2507 | |||
| 7c32365bd3 | |||
| bf6ba727a4 | |||
| 63159702e3 | |||
| 545a873af2 | |||
| db268c6805 | |||
| 2967075c1f | |||
| 4761e4bd43 | |||
| a27dccd0d9 | |||
| 6b8bfc2e2d | |||
| 5b15218174 | |||
| 894cfb2e85 | |||
| 7deae8ea37 | |||
| 03aa7fd06b | |||
| 54ba547c8c | |||
| c1172b6823 | |||
| a91d531db2 | |||
| dd0d4e872f | |||
| 265fd6b91c | |||
| 038b4300ba | |||
| 958d7940f2 | |||
| a3f7ef7002 | |||
| 36eb340c11 | |||
| aa929e8091 | |||
| 2ebfbd5d08 | |||
| 567be2aecf | |||
| 6a6ac99c34 | |||
| 03fc0c868c | |||
| dced287c1c | |||
| bcd426092c | |||
| 62ed7e0a53 | |||
| 566986201f | |||
| a9947cda48 | |||
| 271b0691e2 | |||
| cf46df441a | |||
| aec017e933 | |||
| 3727ef54aa | |||
| 5615f9590b | |||
| e084ddeb41 | |||
| f8760b34b8 | |||
| 9d95c04ab6 | |||
| 62c4713593 | |||
| e3ef3dfb32 | |||
| 7509724e35 | |||
| a41e32c068 | |||
| 3baf326498 | |||
| 8ea9627d51 | |||
| 957feefb2e | |||
| 40b7659078 | |||
| 0427ecc7f4 | |||
| 11560a5451 | |||
| 5bef77c0fb | |||
| 89b85bcf4b | |||
| 694d252ce5 | |||
| 7efc06429c | |||
| ad188fab70 | |||
| b47f9e87f1 | |||
| dddc308167 | |||
| 5919dca5d5 | |||
| 7493426e25 | |||
| 1733e876c4 | |||
| c958422317 | |||
| 6a9277a712 | |||
| 2d336fde73 | |||
| ac3bec5d9e | |||
| 7da60e9937 | |||
| eba5fc84c0 | |||
| 71d8736e7e | |||
| ae1ff4c39a | |||
| f9f998e823 | |||
| e10fc26729 | |||
| 0d6999292c | |||
| 3e7681d4d2 | |||
| c838b8a381 | |||
| 96a279499b | |||
| a3f0b7a37f | |||
| ec87b951d5 | |||
| 2e033b3bb6 | |||
| d8721197b7 | |||
| 4a05b0ea31 | |||
| 663fc4f954 | |||
| 845595b01b | |||
| 2fca8f3444 | |||
| 9324ab8e0e | |||
| e6faf73f4f | |||
| 9f301f8cc6 | |||
| e7c5d1f4f3 | |||
| 91ee948b4e | |||
| c1ed910a51 | |||
| 7414b3596e | |||
| a995c9557c | |||
| 55f06a7ca6 | |||
| e921dca9d6 | |||
| 9ad813d990 | |||
| 9fba3fa673 | |||
| a00278892a | |||
| 196357f6c3 | |||
| 7a736344f9 | |||
| a36824e796 | |||
| 6e2dc64001 | |||
| 68d5acbe48 | |||
| a6b9ceef7b | |||
| 8de579083c | |||
| 6a6b82d1e8 | |||
| ac090c05ae | |||
| 527ef10cda | |||
| 766cf56a3f | |||
| 73714c7cef | |||
| 0485c20331 | |||
| d104ea1b57 | |||
| 41c952a2fa | |||
| 6c09a58baf | |||
| 8d2c5029af | |||
| 8c97e367a2 | |||
| 6423914f01 | |||
| 3b25214433 | |||
| 35a8c5e980 | |||
| 64031777d8 | |||
| 102bf058bc | |||
| 7f51e01be7 | |||
| cb3ac17f43 | |||
| 8dc5092763 | |||
| 4e6bdd1fc7 | |||
| f741861014 | |||
| 5e4a23ea84 | |||
| ea54997bb7 | |||
| da4f51fe2c | |||
| fc9aa1d231 | |||
| ac43b40f33 | |||
| 77201f3805 | |||
| 81f7754a45 | |||
| 2f9360ac08 | |||
| c23be1fd96 | |||
| 1c7bb623f1 | |||
| 75de4e4e67 | |||
| ded940a757 | |||
| b80415b34e | |||
| 2ecc978591 | |||
| de13f7e361 | |||
| 0af4b3da82 | |||
| def651d98e | |||
| a03f5420fa | |||
| 4ab14484ba | |||
| a0f662c114 | |||
| 975d84f3d0 | |||
| c0b708b1f4 | |||
| d93ca26181 | |||
| cf8a0728d8 | |||
| ea24e43c90 | |||
| 75e747a2d2 | |||
| be398a4616 | |||
| 84bd89f00b | |||
| a1c2352dca | |||
| b6ec42334b | |||
| 56fb570267 | |||
| 510d8b9dda | |||
| d8e4895daa | |||
| c20cd907b0 | |||
| c72b4f40bd | |||
| f8d09a9ac3 | |||
| a399a8766d | |||
| 7f103724f3 | |||
| 98ecf0e824 | |||
| 5fb11a77e7 | |||
| d7c72dc279 | |||
| 2c8c88e4b8 | |||
| 9f7347a4f5 | |||
| 13e5590efa | |||
| 77bffa69fd | |||
| 763f8796e0 | |||
| 3be13f57cf | |||
| 31a5363387 | |||
| ef20f228ec | |||
| bc08feaa08 | |||
| ef9ce720b2 | |||
| 4c3d2c10ac | |||
| 0db781b59f | |||
| c94eb4328f | |||
| 47ab187780 | |||
| 020cc54da7 | |||
| dd0a18cf5b | |||
| f726ec740a | |||
| db79b95d22 | |||
| bac2b7643f | |||
| 11449688ba | |||
| b080ebf697 | |||
| 0b0784d40c | |||
| bfb36cac7c | |||
| dd2a1207f4 | |||
| 58b3ce749e | |||
| 6c693ff7b1 | |||
| 95df864d01 | |||
| eaa36a248c | |||
| ca7fe6854b | |||
| 1be3af1e31 | |||
| b8bcb3820a | |||
| 571849f211 | |||
| c8bcbdb3e1 | |||
| 32c187f023 | |||
| dda9519e5e | |||
| 91ff702cf2 | |||
| f7f269aa79 | |||
| 0d34b203d5 | |||
| 34975183d2 | |||
| 545a156942 | |||
| f9d5b28372 | |||
| 8df7812165 | |||
| d1ac2f11d1 | |||
| 5d681c18fe | |||
| a66d651c07 | |||
| e541995e01 | |||
| 6ee17dad03 | |||
| e8d924cd2c | |||
| fa2ea78bda | |||
| 1989a44d4f | |||
| 6b3de00e08 | |||
| 777d397ae7 | |||
| 8b00e72bf6 | |||
| 56281d64b0 | |||
| 024a4ed8d0 | |||
| 789927a043 | |||
| cc0ad0b089 | |||
| a94f3b6211 | |||
| 1340cc0b2e | |||
| c8aedb381b | |||
| 64692e0041 | |||
| f1039a18e4 | |||
| 23b6cf1c24 | |||
| 09f50da821 | |||
| 5110e0ec0e | |||
| edb84b3c97 | |||
| 197ab6357f | |||
| b3e3855931 | |||
| f466bc7cfb | |||
| b77521cbc5 | |||
| 58b91fe6a0 | |||
| a95fbff597 | |||
| 80ee18ee95 | |||
| 6146a0576c | |||
| 73df3ec0de | |||
| d24e4834aa | |||
| 38593ea36c | |||
| 1b232f3214 | |||
| aa1ded5f1a | |||
| e5a20f0c1b | |||
| 9d701cabf6 | |||
| c6c522da04 | |||
| 2251f39fcf | |||
| 01b4e8d59c | |||
| bfd8e96f71 | |||
| e7b84b1637 | |||
| b8ac74a05d | |||
| 38624b1e59 | |||
| a699d9e1de | |||
| cda7a66ec8 | |||
| 36a5313336 | |||
| fedcdcfcd5 | |||
| 11964401c8 | |||
| 48202cfa09 | |||
| 8cac3e9c5c | |||
| 25c481b3ca | |||
| 41258104f6 | |||
| 08a8e6b816 | |||
| 6b254e1a20 | |||
| a00ceb24e1 | |||
| c587632ea0 | |||
| 8f2c662f27 | |||
| dc06e303fc | |||
| dbf38fbeb8 | |||
| 97ffed5ee7 | |||
| 8b49d2d377 | |||
| 6513097d38 | |||
| d1bf2c0ad7 | |||
| 59152cbe80 | |||
| 027f76af96 | |||
| eece4c194a |
+86
@@ -0,0 +1,86 @@
|
||||
*.obj
|
||||
*.pdb
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
[Bb]in
|
||||
[Db]ebug*/
|
||||
obj/
|
||||
[Rr]elease*/
|
||||
_ReSharper*/
|
||||
_NCrunch_*/
|
||||
*.ncrunchsolution
|
||||
*.ncrunchsolution.user
|
||||
*.ncrunchproject
|
||||
*.crunchsolution.cache
|
||||
[Tt]est[Rr]esult*
|
||||
[Bb]uild[Ll]og.*
|
||||
*.[Pp]ublish.xml
|
||||
*.suo
|
||||
[sS]ource
|
||||
[sS]andbox
|
||||
umbraco.config
|
||||
*.vs10x
|
||||
App_Data/TEMP/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]mbraco/[Pp]lugins/*
|
||||
[Uu]mbraco/[Pp]resentation/[Uu]ser[Cc]ontrols/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ss]cripts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Ff]onts/*
|
||||
[Uu]mbraco/[Pp]resentation/[Cc]ss/*
|
||||
|
||||
src/Umbraco.Web.UI/[Cc]ss/*
|
||||
src/Umbraco.Web.UI/App_Code/*
|
||||
src/Umbraco.Web.UI/App_Data/*
|
||||
src/Umbraco.Tests/App_Data/*
|
||||
src/Umbraco.Web.UI/[Mm]edia/*
|
||||
src/Umbraco.Web.UI/[Mm]aster[Pp]ages/*
|
||||
src/Umbraco.Web.UI/[Mm]acro[Ss]cripts/*
|
||||
src/Umbraco.Web.UI/[Xx]slt/*
|
||||
src/Umbraco.Web.UI/[Ii]mages/*
|
||||
src/Umbraco.Web.UI/[Ss]cripts/*
|
||||
src/Umbraco.Web.UI/Web.*.config.transformed
|
||||
|
||||
umbraco/presentation/umbraco/plugins/uComponents/uComponentsInstaller.ascx
|
||||
umbraco/presentation/packages/uComponents/MultiNodePicker/CustomTreeService.asmx
|
||||
_BuildOutput/*
|
||||
build/UmbracoCms.AllBinaries*zip
|
||||
build/UmbracoCms.WebPI*zip
|
||||
build/UmbracoCms*zip
|
||||
build/*.nupkg
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
*.orig
|
||||
src/Umbraco.Tests/config/404handlers.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.cshtml
|
||||
src/Umbraco.Web.UI/[Vv]iews/*.vbhtml
|
||||
src/Umbraco.Tests/[Cc]onfig/umbracoSettings.config
|
||||
src/Umbraco.Web.UI/[Vv]iews/*
|
||||
src/packages/
|
||||
src/packages/repositories.config
|
||||
|
||||
src/Umbraco.Web.UI/[Ww]eb.config
|
||||
*.transformed
|
||||
webpihash.txt
|
||||
|
||||
node_modules
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/routes.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/main.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.js
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.css
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.html
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Aa]ssets/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/
|
||||
src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/
|
||||
build/_BuildOutput/
|
||||
tools/NDepend/
|
||||
src/*.vspx
|
||||
src/*.psess
|
||||
NDependOut/*
|
||||
QueryResult.htm
|
||||
*.ndproj
|
||||
@@ -1,70 +0,0 @@
|
||||
syntax: regexp
|
||||
^src/packages/(?!repositories.config$)
|
||||
web.Template.[a-zA-Z0-9]*.Debug.config
|
||||
|
||||
syntax: glob
|
||||
*.obj
|
||||
*.pdb
|
||||
*.user
|
||||
*.aps
|
||||
*.pch
|
||||
*.vspscc
|
||||
[Bb]in
|
||||
[Db]ebug*/
|
||||
obj/
|
||||
[Rr]elease*/
|
||||
_ReSharper*/
|
||||
_NCrunch_*/
|
||||
*.ncrunchsolution
|
||||
*.ncrunchsolution.user
|
||||
*.ncrunchproject
|
||||
*.crunchsolution.cache
|
||||
[Tt]est[Rr]esult*
|
||||
[Bb]uild[Ll]og.*
|
||||
*.[Pp]ublish.xml
|
||||
*.suo
|
||||
[sS]ource
|
||||
[sS]andbox
|
||||
umbraco.config
|
||||
*.vs10x
|
||||
App_Data\TEMP\*
|
||||
umbraco\presentation\umbraco\plugins\*
|
||||
umbraco\presentation\usercontrols\*
|
||||
umbraco\presentation\scripts\*
|
||||
umbraco\presentation\fonts\*
|
||||
umbraco\presentation\css\*
|
||||
|
||||
src\Umbraco.Web.UI\[Cc]ss\*
|
||||
src\Umbraco.Web.UI\App_Code\*
|
||||
src\Umbraco.Web.UI\App_Data\*
|
||||
src\Umbraco.Tests\App_Data\*
|
||||
src\Umbraco.Web.UI\[Mm]edia\*
|
||||
src\Umbraco.Web.UI\[Mm]aster[Pp]ages\*
|
||||
src\Umbraco.Web.UI\[Mm]acro[Ss]cripts\*
|
||||
src\Umbraco.Web.UI\[Xx]slt\*
|
||||
src\Umbraco.Web.UI\[Ii]mages\*
|
||||
src\Umbraco.Web.UI\[Ss]cripts\*
|
||||
src\Umbraco.Web.UI\Web.*.config.transformed
|
||||
|
||||
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
|
||||
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
|
||||
_BuildOutput/*
|
||||
*.ncrunchsolution
|
||||
build/UmbracoCms.AllBinaries*zip
|
||||
build/UmbracoCms.WebPI*zip
|
||||
build/UmbracoCms*zip
|
||||
build/*.nupkg
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
*.orig
|
||||
src/Umbraco.Tests/config/404handlers.config
|
||||
src/Umbraco.Web.UI/Views/*.cshtml
|
||||
src/Umbraco.Web.UI/Views/*.vbhtml
|
||||
src/Umbraco.Tests/config/umbracoSettings.config
|
||||
src/Umbraco.Web.UI/App_Plugins/*
|
||||
src/Umbraco.Web.UI/Views/*
|
||||
src/packages/
|
||||
|
||||
src\Umbraco.Web.UI\[W]eb.config
|
||||
*.transformed
|
||||
@@ -1,31 +0,0 @@
|
||||
d0aba247db91d1b70c39c6397b965ca370a67497 Sprint-Juno-A
|
||||
0b8f67be2ca8faf008151d87f232c698de69e735 Release-4.5.0
|
||||
5960c073250926d202861a09472f5f334da6e283 Sprint-Juno-B
|
||||
f15d4ff81a8368e9d42788f7e0ae726f7a70a3b1 Release-4.0.3
|
||||
283065df4d3c27245267709dd2644a479c4f62a5 Release-4.0.4.2
|
||||
ffc34b23e1a03785e4098afa4290d8c03cf10115 Release-4.5.2
|
||||
d03fcffb8834a9583a56813bb44b6abbd9f042cc Release-4.6.0
|
||||
1809f7b2593270c192cd47bdcfdb392100686f79 4.7.2
|
||||
488779dec0ceb1d2874bcef906241b919325c904 4.8.0-beta
|
||||
096f20bb0575d6199f20fcb3147b63554e765a74 Release-4.8.0
|
||||
8f8a203857886b373148af29edd57460a42940be Release-4.8.1
|
||||
de73e687ddf6086ed52b6554676c1632865d07f2 Release-4.9.0
|
||||
8d7d8609e2e4b971da99cd97f72132ce85ce3333 Release-4.9.1
|
||||
f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0
|
||||
20e4dff821d8ac2527a5353618fa1a23ea1d8b34 Release-4.11.0
|
||||
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
|
||||
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
|
||||
6eb5f2fb5a88aa29ea544499df9160a1b31b5638 Release-4.11.1
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
|
||||
0000000000000000000000000000000000000000 4.11.2
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 Release-4.11.2
|
||||
77db220b89e166b3c0736ed321ecfd6416cddbcd Release-4.11.2.1
|
||||
54cde33b809dcb3a1f7e7ae0d5375f6dd0d89c8d Release-4.11.2.2
|
||||
ff3bb24ea0c915878396a6ae27f1ff164e8ac150 Release-6.0.0-beta
|
||||
56015ac26f5ab60e3c61b1d09075297b660afa07 Release-6.0.0-RC
|
||||
1719fbd857f28b376639ac2aa0abada0ef2e7560 Release-6.0.0
|
||||
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
|
||||
14338b0ab1738fbd8987677ecdb9a73d79fc229d release-4.11.6
|
||||
b247b35d821144849f551e02da8ba719f91d5fb0 Release-6.0.2
|
||||
aed55cba29009ad3db48880a7cfb66407ce9805f release-6.0.3
|
||||
@@ -0,0 +1,9 @@
|
||||
# The MIT License (MIT) #
|
||||
|
||||
Copyright (c) 2013 Umbraco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,33 @@
|
||||
Umbraco CMS
|
||||
===========
|
||||
## Watch a five minute introduction video ##
|
||||
|
||||
[](http://umbraco.org/help-and-support/video-tutorials/getting-started/what-is-umbraco)
|
||||
|
||||
## Umbraco - the simple, flexible and friendly ASP.NET CMS ##
|
||||
|
||||
**More than 177,000 sites trust Umbraco**
|
||||
|
||||
For the first time on the Microsoft platform a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. It's a developers dream and your users will love it too.
|
||||
|
||||
Used by more than 177,000 active websites including [http://daviscup.com](http://daviscup.com), [http://heinz.com](http://heinz.com), [http://peugeot.com](http://peugeot.com), [http://www.hersheys.com/](http://www.hersheys.com/) and **The Official ASP.NET and IIS.NET website from Microsoft** ([http://asp.net](http://asp.net) / [http://iis.net](http://iis.net)) you can be sure that the technology is proven, stable and scales.
|
||||
|
||||
To view more examples please visit [http://umbraco.com/why-umbraco/#caseStudies](http://umbraco.com/why-umbraco/#caseStudies)
|
||||
|
||||
## Downloading ##
|
||||
|
||||
The downloadable Umbraco releases live at [http://our.umbraco.org/download](http://our.umbraco.org/download).
|
||||
|
||||
## Forums ##
|
||||
|
||||
We have a forum running on [http://our.umbraco.org](http://our.umbraco.org). The discussions group on [Google Groups](https://groups.google.com/forum/#!forum/umbraco-dev) is for discussions on developing the core, and not on Umbraco-implementations or extensions in general. For those topics, please use [http://our.umbraco.org](http://our.umbraco.org).
|
||||
|
||||
## Contribute to Umbraco ##
|
||||
|
||||
If you want to contribute back to Umbraco you should check out our [guide to contributing](http://our.umbraco.org/contribute).
|
||||
|
||||
## Found a bug? ##
|
||||
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our [online guide for reporting issues](http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature).
|
||||
|
||||
To view existing issues please visit [http://issues.umbraco.org](http://issues.umbraco.org)
|
||||
+3
-1
@@ -1,10 +1,12 @@
|
||||
@ECHO OFF
|
||||
SET release=6.0.4
|
||||
SET release=6.1.6
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
|
||||
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment%
|
||||
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Code\dummy.txt
|
||||
|
||||
+217
-147
@@ -1,19 +1,19 @@
|
||||
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!--
|
||||
<!--
|
||||
****************************************************
|
||||
INCLUDES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
|
||||
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
<PropertyGroup>
|
||||
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
|
||||
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
|
||||
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
@@ -53,65 +53,69 @@
|
||||
</UsingTask>
|
||||
|
||||
|
||||
<!--
|
||||
<!--
|
||||
****************************************************
|
||||
VARIABLES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<!-- NB: BUILD_NUMBER is passed in by the build server -->
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
<BuildFolder>_BuildOutput\</BuildFolder>
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
</PropertyGroup>
|
||||
<!-- NB: BUILD_NUMBER is passed in by the build server -->
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)media" />
|
||||
<SystemFolders Include="$(WebAppFolder)masterpages" />
|
||||
<SystemFolders Include="$(WebAppFolder)scripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)css" />
|
||||
<SystemFolders Include="$(WebAppFolder)macroScripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)xslt" />
|
||||
<SystemFolders Include="$(WebAppFolder)usercontrols" />
|
||||
<SystemFolders Include="$(WebAppFolder)Views" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
<BuildFolder>_BuildOutput\</BuildFolder>
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
<ExaminePDFPath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF\</ExaminePDFPath>
|
||||
<ExamineAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.Azure\</ExamineAzurePath>
|
||||
<ExaminePDFAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF.Azure\</ExaminePDFAzurePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)Media" />
|
||||
<SystemFolders Include="$(WebAppFolder)Masterpages" />
|
||||
<SystemFolders Include="$(WebAppFolder)Scripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)Css" />
|
||||
<SystemFolders Include="$(WebAppFolder)MacroScripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)Xslt" />
|
||||
<SystemFolders Include="$(WebAppFolder)UserControls" />
|
||||
<SystemFolders Include="$(WebAppFolder)Views" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
****************************************************
|
||||
TARGETS
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
|
||||
<Message Text="Build finished" />
|
||||
<Message Text="Build finished" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
|
||||
@@ -120,117 +124,183 @@
|
||||
</ItemGroup>
|
||||
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
|
||||
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
<Message Text="Deleting $(BuildFolder)" Importance="high" />
|
||||
<RemoveDir Directories="$(BuildFolder)" />
|
||||
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
|
||||
</Target>
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
|
||||
<!-- Clean folders -->
|
||||
<RemoveDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)umbraco" />
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
<Message Text="Deleting $(BuildFolder)" Importance="high" />
|
||||
<RemoveDir Directories="$(BuildFolder)" />
|
||||
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy fresh built umbraco files -->
|
||||
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
|
||||
|
||||
<!-- Copy Web Pi template files -->
|
||||
<ItemGroup>
|
||||
<WebPiFiles Include="..\src\WebPi\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
|
||||
<!-- Clean folders -->
|
||||
<RemoveDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)umbraco" />
|
||||
|
||||
<Copy SourceFiles="@(WebPiFiles)"
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
<!-- Copy fresh built umbraco files -->
|
||||
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
|
||||
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
<!-- Copy Web Pi template files -->
|
||||
<ItemGroup>
|
||||
<WebPiFiles Include="..\src\WebPi\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
<Copy SourceFiles="@(WebPiFiles)"
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
|
||||
/>
|
||||
</ItemGroup>
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
</Target>
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
|
||||
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
|
||||
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
|
||||
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
|
||||
</CreateItem>
|
||||
<Message Text="Starting to offset timestamps" Importance="high" />
|
||||
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
|
||||
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
|
||||
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
|
||||
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
|
||||
</CreateItem>
|
||||
<Message Text="Starting to offset timestamps" Importance="high" />
|
||||
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigFile)"
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
<!-- Copy the config files and rename them to *.config.transform -->
|
||||
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<ConfigFiles Include="$(WebAppFolder)config\*.config" />
|
||||
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigFile)"
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
<Copy SourceFiles="@(ConfigFiles)"
|
||||
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(XmlDocumentationFiles)"
|
||||
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="SetVersionNumber">
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigTransformFile)"
|
||||
DestinationFiles="$(ConfigsFolder)Web.config.transform"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CleanupPresentation">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<Copy SourceFiles="@(XmlDocumentationFiles)"
|
||||
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
|
||||
<!-- Also, it places umbraco.XmlSerializers.dll in the root, even though it's also in the bin folder. Kill! -->
|
||||
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
|
||||
<XmlSerializersDll Include="$(WebAppFolder)umbraco.XmlSerializers.dll" />
|
||||
</ItemGroup>
|
||||
<RemoveDir Directories="@(PresentationFolderToDelete)" />
|
||||
<Delete Files="@(XmlSerializersDll)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
|
||||
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<!-- Build the Umbraco.Web.UI project -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileExternalExamineProjects" DependsOnTargets="SetVersionNumber">
|
||||
<Message Text="Building externally shipped examine projects" Importance="high" />
|
||||
|
||||
<!-- First remove old files from the examine builds -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteBeforeBuild Include="$(ExaminePDFPath)*;$(ExamineAzurePath)*"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteBeforeBuild)" />
|
||||
<!--
|
||||
Build the UmbracoExamine.PDF.Azure library ... this builds the 3 projects that we want to bundle separately so no need to build each one separately .
|
||||
We'll just build this one and then manually copy the DLLs to where we want them.
|
||||
-->
|
||||
<MSBuild Projects="..\src\UmbracoExamine.PDF.Azure\UmbracoExamine.PDF.Azure.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);PipelineDependsOnBuild=False;OutDir=$(ExaminePDFAzurePath);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
<ItemGroup>
|
||||
<ExaminePDFFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.pdf;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.xml;$(ExaminePDFAzurePath)**\itextsharp.dll" />
|
||||
<ExamineAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.xml" />
|
||||
<ExaminePDFAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.xml" />
|
||||
</ItemGroup>
|
||||
<!-- Now copy the built files to their correct deployment folders-->
|
||||
<Copy SourceFiles="@(ExaminePDFFiles)"
|
||||
DestinationFolder="$(ExaminePDFPath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(ExamineAzureFiles)"
|
||||
DestinationFolder="$(ExamineAzurePath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<!-- Then just delete the files we don't want to ship in the UmbracoExamine.Azure.PDF folder -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteAfterBuild Include="$(ExaminePDFAzurePath)*" Exclude="$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.dll;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.pdb;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.xml"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteAfterBuild)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<FileUpdate
|
||||
<FileUpdate
|
||||
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
|
||||
ReplacementText="$(BUILD_RELEASE)"/>
|
||||
@@ -238,5 +308,5 @@
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="CurrentComment { get { return "([a-zA-Z]+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/>
|
||||
</Target>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-16"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>6.0.0-alpha</version>
|
||||
<version>6.2.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
@@ -14,59 +14,57 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.20710.0]" />
|
||||
<dependency id="ServiceStack.Text" version="3.9.21" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="4.0" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="4.0" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.6.5]" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.7.0, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.7.0, 2.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\ClientDependency.Core.dll" target="lib\ClientDependency.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\ClientDependency.Core.Mvc.dll" target="lib\ClientDependency.Core.Mvc.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\CookComputing.XmlRpcV2.dll" target="lib\CookComputing.XmlRpcV2.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Examine.dll" target="lib\Examine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\HtmlAgilityPack.dll" target="lib\HtmlAgilityPack.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\ICSharpCode.SharpZipLib.dll" target="lib\ICSharpCode.SharpZipLib.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Lucene.Net.dll" target="lib\Lucene.Net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Lucene.Net.xml" target="lib\Lucene.Net.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\MySql.Data.dll" target="lib\MySql.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.47x.dll" target="lib\Our.Umbraco.uGoLive.47x.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.Checks.dll" target="lib\Our.Umbraco.uGoLive.Checks.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.dll" target="lib\Our.Umbraco.uGoLive.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.xml" target="lib\umbraco.macroRenderings.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.dll" target="lib\umbraco.webservices.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.webservices.xml" target="lib\umbraco.webservices.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
</files>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Examine.dll" target="lib\Examine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.47x.dll" target="lib\Our.Umbraco.uGoLive.47x.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.Checks.dll" target="lib\Our.Umbraco.uGoLive.Checks.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Our.Umbraco.uGoLive.dll" target="lib\Our.Umbraco.uGoLive.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.dll" target="lib\umbraco.macroRenderings.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.macroRenderings.xml" target="lib\umbraco.macroRenderings.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.XmlSerializers.dll" target="lib\umbraco.XmlSerializers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-16"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms</id>
|
||||
<version>6.0.0-alpha</version>
|
||||
<version>6.1.2</version>
|
||||
<title>Umbraco Cms</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
@@ -10,8 +10,8 @@
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Installs Umbraco Cms in your Visual Studio ASP.NET Webforms project</description>
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET Webforms project</summary>
|
||||
<description>Installs Umbraco Cms in your Visual Studio ASP.NET project</description>
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET project</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
@@ -21,14 +21,14 @@
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="Content\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
|
||||
<file src="..\_BuildOutput\WebApp\config\*.config" target="Content\config" />
|
||||
<file src="..\_BuildOutput\Configs\**" target="Content\config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
|
||||
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
|
||||
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" />
|
||||
<file src="..\_BuildOutput\WebApp\masterpages\**" target="Content\masterpages" />
|
||||
<file src="..\_BuildOutput\WebApp\media\**" target="Content\media" />
|
||||
<file src="..\_BuildOutput\WebApp\scripts\**" target="Content\scripts" />
|
||||
<file src="..\_BuildOutput\WebApp\usercontrols\**" target="Content\usercontrols" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" exclude="..\_BuildOutput\WebApp\Views\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\xslt\**" target="Content\xslt" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="Content\Web.config" />
|
||||
@@ -36,7 +36,7 @@
|
||||
<file src="..\_BuildOutput\WebApp\App_Code\**" target="UmbracoFiles\App_Code" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\config\**" target="UmbracoFiles\config" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\install\**" target="UmbracoFiles\install" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
@@ -44,5 +44,6 @@
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="tools\install.ps1" target="tools\install.ps1" />
|
||||
<file src="tools\Readme.txt" target="tools\Readme.txt" />
|
||||
<file src="build\**" target="build" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForPackageDependsOn>
|
||||
|
||||
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
AddUmbracoFilesToOutput;
|
||||
$(CopyAllFilesToSingleFolderForPackageDependsOn);
|
||||
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="AddUmbracoFilesToOutput">
|
||||
<ItemGroup>
|
||||
<UmbracoFiles Include=".\umbraco\**\*;" />
|
||||
<UmbracoClientFiles Include=".\umbraco_client\**\*;" />
|
||||
<AppBrowsersFiles Include=".\App_Browsers\**\*" />
|
||||
<FilesForPackagingFromProject Include="%(UmbracoFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(UmbracoClientFiles.Identity)">
|
||||
<DestinationRelativePath>umbraco_client\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
<FilesForPackagingFromProject Include="%(AppBrowsersFiles.Identity)">
|
||||
<DestinationRelativePath>App_Browsers\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
|
||||
</FilesForPackagingFromProject>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,15 +1,19 @@
|
||||
A note about running Umbraco from Visual Studio.
|
||||
|
||||
When upgrading your website using nuget a backup of config files and web.config will be created and the files will
|
||||
be overwritten with those from the current release. This means that you'll have to merge the files if you made any
|
||||
changes to the previous config files.
|
||||
When upgrading your website using nuget a backup of config files and web.config will be created. Only the web.config will
|
||||
be overwritten by default to ensure that it has the necessary settings from the current release. This means that you'll
|
||||
have to merge the files if you made any changes to the previous config files.
|
||||
The config files found in the config folder will usually not be changed for patch releases, so they can usually be skipped,
|
||||
but the web.config will have to have its previous "umbracoConfigurationStatus"-appsetting and "umbracoDbDSN" connection string
|
||||
copied over (as a minimum).
|
||||
|
||||
It's not possible to create a deploy package from Visual Studio, which contains everything out of the box. This is
|
||||
due to a number of files and folders that are not added to the Visual Studio project. These folders include:
|
||||
install, umbraco and umbraco_client.
|
||||
A custom deploy script will be added in a later release.
|
||||
This nuget package includes build targets that extends the creation of a deploy package, which is generated by
|
||||
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
|
||||
Publish this won't affect you.
|
||||
These folders will now be automatically included when creating a deploy package or publishing to the file system:
|
||||
umbraco and umbraco_client.
|
||||
|
||||
Please read the release notes on Codeplex:
|
||||
http://umbraco.codeplex.com/releases
|
||||
Please read the release notes on our.umbraco.org:
|
||||
http://our.umbraco.org/contribute/releases
|
||||
|
||||
- Umbraco
|
||||
@@ -21,4 +21,7 @@ if ($project) {
|
||||
$projectDestinationPath = Split-Path $project.FullName -Parent
|
||||
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
|
||||
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
|
||||
|
||||
# Open readme.txt file
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||
<!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
|
||||
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
||||
<!-- The official NuGet package source (https://nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||
<!--
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||
@@ -54,10 +55,10 @@
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
|
||||
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||
<ResolveReferencesDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
RestorePackages;
|
||||
$(ResolveReferencesDependsOn);
|
||||
</ResolveReferencesDependsOn>
|
||||
$(BuildDependsOn);
|
||||
</BuildDependsOn>
|
||||
|
||||
<!-- Make the build depend on restore packages -->
|
||||
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
|
||||
@@ -75,7 +76,7 @@
|
||||
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||
parallel builds will have to wait for it to complete.
|
||||
-->
|
||||
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT" />
|
||||
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_DownloadNuGet">
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
|
||||
@@ -15,33 +18,53 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// one per AppDomain, represents the global Umbraco application
|
||||
/// </remarks>
|
||||
public class ApplicationContext
|
||||
public class ApplicationContext : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
|
||||
:this()
|
||||
: this(dbContext, serviceContext, true)
|
||||
{
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache)
|
||||
: this(enableCache)
|
||||
{
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empty constructor normally reserved for unit tests when a DatabaseContext or a ServiceContext is not
|
||||
/// necessarily required or needs to be set after construction.
|
||||
/// </summary>
|
||||
internal ApplicationContext()
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
? new CacheHelper(new Cache())
|
||||
: new CacheHelper(HttpRuntime.Cache);
|
||||
internal ApplicationContext() : this(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to specify if we will enable application cache or not
|
||||
/// </summary>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(bool enableCache)
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
? new CacheHelper(new System.Web.Caching.Cache(), enableCache)
|
||||
: new CacheHelper(HttpRuntime.Cache, enableCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
@@ -197,5 +220,54 @@ namespace Umbraco.Core
|
||||
}
|
||||
internal set { _services = value; }
|
||||
}
|
||||
|
||||
|
||||
private volatile bool _disposed;
|
||||
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// This will dispose and reset all resources used to run the application
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// IMPORTANT: Never dispose this object if you require the Umbraco application to run, disposing this object
|
||||
/// is generally used for unit testing and when your application is shutting down after you have booted Umbraco.
|
||||
/// </remarks>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
// Only operate if we haven't already disposed
|
||||
if (_disposed) return;
|
||||
|
||||
using (new WriteLock(_disposalLocker))
|
||||
{
|
||||
// Check again now we're inside the lock
|
||||
if (_disposed) return;
|
||||
|
||||
//clear the cache
|
||||
if (ApplicationCache != null)
|
||||
{
|
||||
ApplicationCache.ClearAllCache();
|
||||
}
|
||||
//reset all resolvers
|
||||
ResolverCollection.ResetAll();
|
||||
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
|
||||
Resolution.Reset();
|
||||
|
||||
//reset the instance objects
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
{
|
||||
if (DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
}
|
||||
this.DatabaseContext = null;
|
||||
this.Services = null;
|
||||
this._isReady = false; //set the internal field
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A plugin type that allows developers to execute code during the Umbraco bootup process
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Allows you to override the methods that you would like to execute code for: ApplicationInitialized, ApplicationStarting, ApplicationStarted.
|
||||
///
|
||||
/// By default none of these methods will execute if the Umbraco application is not configured or if the Umbraco database is not configured, however
|
||||
/// if you need these methods to execute even if either of these are not configured you can override the properties:
|
||||
/// ExecuteWhenApplicationNotConfigured and ExecuteWhenDatabaseNotConfigured
|
||||
/// </remarks>
|
||||
public abstract class ApplicationEventHandler : IApplicationEventHandler
|
||||
{
|
||||
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationInitialized(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationStarting(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationStarted(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable method to execute when the ApplicationContext is created and other static objects that require initialization have been setup
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OVerridable method to execute when All resolvers have been initialized but resolution is not frozen so they can be modified in this method
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable method to execute when Bootup is completed, this allows you to perform any other bootup logic required for the application.
|
||||
/// Resolution is frozen so now they can be used to resolve instances.
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if the methods should execute based on the configuration status of the application.
|
||||
/// </summary>
|
||||
/// <param name="applicationContext"></param>
|
||||
/// <returns></returns>
|
||||
private bool ShouldExecute(ApplicationContext applicationContext)
|
||||
{
|
||||
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!applicationContext.IsConfigured && ExecuteWhenApplicationNotConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flag to determine if the overridable methods for this class will execute even if the
|
||||
/// Umbraco application is not configured
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// An Umbraco Application is not configured when it requires a new install or upgrade. When the latest version in the
|
||||
/// assembly does not match the version in the config.
|
||||
/// </remarks>
|
||||
protected virtual bool ExecuteWhenApplicationNotConfigured
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flag to determine if the overridable methods for this class will execute even if the
|
||||
/// Umbraco database is not configured
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Umbraco database is not configured when we cannot connect to the database or when the database tables are not installed.
|
||||
/// </remarks>
|
||||
protected virtual bool ExecuteWhenDatabaseNotConfigured
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,41 @@ namespace Umbraco.Core
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the App_Code assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAppCodeAssembly(this Assembly assembly)
|
||||
{
|
||||
if (assembly.FullName.StartsWith("App_Code"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Assembly.Load("App_Code");
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
//this will occur if it cannot load the assembly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the assembly is the compiled global asax.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsGlobalAsaxAssembly(this Assembly assembly)
|
||||
{
|
||||
//only way I can figure out how to test is by the name
|
||||
return assembly.FullName.StartsWith("App_global.asax");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file used to load the assembly
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constants storing cache keys used in caching
|
||||
/// </summary>
|
||||
public static class CacheKeys
|
||||
{
|
||||
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
|
||||
public const string ApplicationsCacheKey = "ApplicationCache";
|
||||
|
||||
public const string UserTypeCacheKey = "UserTypeCache";
|
||||
|
||||
public const string ContentItemCacheKey = "contentItem";
|
||||
|
||||
public const string MediaCacheKey = "UL_GetMedia";
|
||||
|
||||
public const string MacroXsltCacheKey = "macroXslt_";
|
||||
public const string MacroCacheKey = "UmbracoMacroCache";
|
||||
public const string MacroHtmlCacheKey = "macroHtml_";
|
||||
public const string MacroControlCacheKey = "macroControl_";
|
||||
public const string MacroHtmlDateAddedCacheKey = "macroHtml_DateAdded_";
|
||||
public const string MacroControlDateAddedCacheKey = "macroControl_DateAdded_";
|
||||
|
||||
public const string MemberLibraryCacheKey = "UL_GetMember";
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
|
||||
public const string UserCacheKey = "UmbracoUser";
|
||||
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
|
||||
|
||||
public const string ContentTypeCacheKey = "UmbracoContentType";
|
||||
|
||||
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
|
||||
|
||||
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
|
||||
|
||||
public const string LanguageCacheKey = "UmbracoLanguageCache";
|
||||
|
||||
public const string DomainCacheKey = "UmbracoDomainList";
|
||||
|
||||
public const string StylesheetCacheKey = "UmbracoStylesheet";
|
||||
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
|
||||
|
||||
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a basic cache provider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
|
||||
/// </remarks>
|
||||
internal abstract class CacheProviderBase
|
||||
{
|
||||
public abstract void ClearAllCache();
|
||||
public abstract void ClearCacheItem(string key);
|
||||
public abstract void ClearCacheObjectTypes(string typeName);
|
||||
public abstract void ClearCacheObjectTypes<T>();
|
||||
public abstract void ClearCacheByKeySearch(string keyStartsWith);
|
||||
public abstract void ClearCacheByKeyExpression(string regexString);
|
||||
public abstract IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith);
|
||||
public abstract T GetCacheItem<T>(string cacheKey);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
|
||||
/// when cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
public abstract class CacheRefresherBase<TInstanceType> : ICacheRefresher
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that is raised when cache is updated on an individual server
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This event will fire on each server configured for an Umbraco project whenever a cache refresher
|
||||
/// is updated.
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<TInstanceType, CacheRefresherEventArgs> CacheUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Raises the event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
protected static void OnCacheUpdated(TInstanceType sender, CacheRefresherEventArgs args)
|
||||
{
|
||||
if (CacheUpdated != null)
|
||||
{
|
||||
CacheUpdated(sender, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the real instance of the object ('this') for use in strongly typed events
|
||||
/// </summary>
|
||||
protected abstract TInstanceType Instance { get; }
|
||||
|
||||
public abstract Guid UniqueIdentifier { get; }
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
public virtual void RefreshAll()
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(null, MessageType.RefreshAll));
|
||||
}
|
||||
|
||||
public virtual void Refresh(int id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
|
||||
}
|
||||
|
||||
public virtual void Remove(int id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RemoveById));
|
||||
}
|
||||
|
||||
public virtual void Refresh(Guid id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Event args for cache refresher updates
|
||||
/// </summary>
|
||||
public class CacheRefresherEventArgs : EventArgs
|
||||
{
|
||||
public CacheRefresherEventArgs(object msgObject, MessageType type)
|
||||
{
|
||||
MessageType = type;
|
||||
MessageObject = msgObject;
|
||||
}
|
||||
public object MessageObject { get; private set; }
|
||||
public MessageType MessageType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
|
||||
/// </summary>
|
||||
internal class HttpRuntimeCacheProvider : RuntimeCacheProviderBase
|
||||
{
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything in umbraco's runtime cache, which means that not only
|
||||
/// umbraco content is removed, but also other cache items from pages running in
|
||||
/// the same application / website. Use with care :-)
|
||||
/// </summary>
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
var cacheEnumerator = _cache.GetEnumerator();
|
||||
while (cacheEnumerator.MoveNext())
|
||||
{
|
||||
_cache.Remove(cacheEnumerator.Key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache with the given key
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
// NH 10 jan 2012
|
||||
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
|
||||
lock (Locker)
|
||||
{
|
||||
if (_cache[key] == null) return;
|
||||
_cache.Remove(key); ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type name as the
|
||||
/// input parameter. (using [object].GetType())
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (_cache[c.Key.ToString()] != null
|
||||
&& _cache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName))
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type specified
|
||||
/// </summary>
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (_cache[c.Key.ToString()] != null
|
||||
&& _cache[c.Key.ToString()].GetType() == typeof(T))
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith))
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString))
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return (from DictionaryEntry c in _cache
|
||||
where c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith)
|
||||
select c.Value.TryConvertTo<T>()
|
||||
into attempt
|
||||
where attempt.Success
|
||||
select attempt.Result).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
return default(TT);
|
||||
}
|
||||
return result.TryConvertTo<TT>().Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan? timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="syncLock"></param>
|
||||
/// <returns></returns>
|
||||
private TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency, TimeSpan? timeout, Func<TT> getCacheItem, object syncLock)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency,
|
||||
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
|
||||
TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.TryConvertTo<TT>().Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, null, null, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
object result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency,
|
||||
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
|
||||
TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Strongly type cache refresher that is able to refresh cache of real instances of objects as well as IDs
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks>
|
||||
/// This is much better for performance when we're not running in a load balanced environment so we can refresh the cache
|
||||
/// against a already resolved object instead of looking the object back up by id.
|
||||
/// </remarks>
|
||||
interface ICacheRefresher<T> : ICacheRefresher
|
||||
{
|
||||
void Refresh(T instance);
|
||||
void Remove(T instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache refresher that supports refreshing or removing cache based on a custom Json payload
|
||||
/// </summary>
|
||||
interface IJsonCacheRefresher : ICacheRefresher
|
||||
{
|
||||
/// <summary>
|
||||
/// Refreshes, clears, etc... any cache based on the information provided in the json
|
||||
/// </summary>
|
||||
/// <param name="jsonPayload"></param>
|
||||
void Refresh(string jsonPayload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for json cache refreshers that ensures the correct events are raised when
|
||||
/// cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
public abstract class JsonCacheRefresherBase<TInstanceType> : CacheRefresherBase<TInstanceType>, IJsonCacheRefresher
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
|
||||
public virtual void Refresh(string jsonPayload)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class NullCacheProvider : RuntimeCacheProviderBase
|
||||
{
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a runtime cache provider
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, REQUEST CACHE, ETC...
|
||||
/// </remarks>
|
||||
internal abstract class RuntimeCacheProviderBase : CacheProviderBase
|
||||
{
|
||||
public abstract T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache provider that statically caches everything in an in memory dictionary
|
||||
/// </summary>
|
||||
internal class StaticCacheProvider : CacheProviderBase
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, object> _staticCache = new ConcurrentDictionary<string, object>();
|
||||
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
_staticCache.Clear();
|
||||
}
|
||||
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (_staticCache[key] != null
|
||||
&& _staticCache[key].GetType().ToString().InvariantEquals(typeName))
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (_staticCache[key] != null
|
||||
&& _staticCache[key].GetType() == typeof(T))
|
||||
{
|
||||
object val;
|
||||
_staticCache.TryRemove(key, out val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (key.InvariantStartsWith(keyStartsWith))
|
||||
{
|
||||
ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
foreach (var key in _staticCache.Keys)
|
||||
{
|
||||
if (Regex.IsMatch(key, regexString))
|
||||
{
|
||||
ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return (from KeyValuePair<string, object> c in _staticCache
|
||||
where c.Key.InvariantStartsWith(keyStartsWith)
|
||||
select c.Value.TryConvertTo<T>()
|
||||
into attempt
|
||||
where attempt.Success
|
||||
select attempt.Result).ToList();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey)
|
||||
{
|
||||
var result = _staticCache[cacheKey];
|
||||
if (result == null)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
return result.TryConvertTo<T>().Result;
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
|
||||
{
|
||||
return (T)_staticCache.GetOrAdd(cacheKey, getCacheItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
|
||||
/// when cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
/// <typeparam name="TEntityType">The entity type that this refresher can update cache for</typeparam>
|
||||
public abstract class TypedCacheRefresherBase<TInstanceType, TEntityType> : CacheRefresherBase<TInstanceType>, ICacheRefresher<TEntityType>
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
public virtual void Refresh(TEntityType instance)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RefreshByInstance));
|
||||
}
|
||||
|
||||
public virtual void Remove(TEntityType instance)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RemoveByInstance));
|
||||
}
|
||||
}
|
||||
}
|
||||
+479
-81
@@ -3,8 +3,10 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -13,31 +15,198 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Class that is exposed by the ApplicationContext for application wide caching purposes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
|
||||
/// </remarks>
|
||||
public class CacheHelper
|
||||
public class CacheHelper
|
||||
{
|
||||
private readonly Cache _cache;
|
||||
private readonly bool _enableCache;
|
||||
private readonly CacheProviderBase _staticCache;
|
||||
private readonly CacheProviderBase _nullStaticCache = new NullCacheProvider();
|
||||
private readonly RuntimeCacheProviderBase _httpCache;
|
||||
private readonly RuntimeCacheProviderBase _nullHttpCache = new NullCacheProvider();
|
||||
|
||||
public CacheHelper(System.Web.Caching.Cache cache)
|
||||
: this(cache, true)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache)
|
||||
: this(new HttpRuntimeCacheProvider(cache), enableCache)
|
||||
{
|
||||
}
|
||||
|
||||
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, bool enableCache)
|
||||
: this(httpCacheProvider, new StaticCacheProvider(), enableCache)
|
||||
{
|
||||
}
|
||||
|
||||
internal CacheHelper(RuntimeCacheProviderBase httpCacheProvider, CacheProviderBase staticCacheProvider, bool enableCache)
|
||||
{
|
||||
_httpCache = httpCacheProvider;
|
||||
_staticCache = staticCacheProvider;
|
||||
_enableCache = enableCache;
|
||||
}
|
||||
|
||||
#region Static cache
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything in umbraco's runtime cache, which means that not only
|
||||
/// umbraco content is removed, but also other cache items from pages running in
|
||||
/// the same application / website. Use with care :-)
|
||||
/// Clears the item in umbraco's static cache
|
||||
/// </summary>
|
||||
internal void ClearAllStaticCache()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's static cache with the given key
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
internal void ClearStaticCacheItem(string key)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheItem(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the static cache with the System.Type name as the
|
||||
/// input parameter. (using [object].GetType())
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
internal void ClearStaticCacheObjectTypes(string typeName)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the static cache with the System.Type specified
|
||||
/// </summary>
|
||||
internal void ClearStaticCacheObjectTypes<T>()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all static cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
internal void ClearStaticCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
internal void ClearStaticCacheByKeyExpression(string regexString)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullStaticCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
else
|
||||
{
|
||||
_staticCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
}
|
||||
|
||||
internal IEnumerable<T> GetStaticCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a static cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetStaticCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the static cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetStaticCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullStaticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _staticCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Runtime/Http Cache
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache
|
||||
/// </summary>
|
||||
public void ClearAllCache()
|
||||
{
|
||||
var cacheEnumerator = _cache.GetEnumerator();
|
||||
while (cacheEnumerator.MoveNext())
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_cache.Remove(cacheEnumerator.Key.ToString());
|
||||
_nullHttpCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,12 +216,13 @@ namespace Umbraco.Core
|
||||
/// <param name="key">Key</param>
|
||||
public void ClearCacheItem(string key)
|
||||
{
|
||||
// NH 10 jan 2012
|
||||
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
|
||||
lock (Locker)
|
||||
if (!_enableCache)
|
||||
{
|
||||
if (_cache[key] == null) return;
|
||||
_cache.Remove(key);;
|
||||
_nullHttpCache.ClearCacheItem(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheItem(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,19 +234,28 @@ namespace Umbraco.Core
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
try
|
||||
if (!_enableCache)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (var c in from DictionaryEntry c in _cache where _cache[c.Key.ToString()] != null && _cache[c.Key.ToString()].GetType().ToString() == typeName select c)
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
_nullHttpCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
_httpCache.ClearCacheObjectTypes(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type specified
|
||||
/// </summary>
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,79 +265,298 @@ namespace Umbraco.Core
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (var c in from DictionaryEntry c in _cache where c.Key is string && ((string)c.Key).StartsWith(keyStartsWith) select c)
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used only for legacy purposes as I did not want to change all of the locking to one lock found on this object,
|
||||
/// however, the reason this is used for legacy purposes is because I see zero reason to use different sync locks, just the one
|
||||
/// lock (Locker) on this class should be sufficient.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="syncLock"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency, TimeSpan timeout, Func<TT> getCacheItem, object syncLock)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency, DateTime.Now.Add(timeout), TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (TT)result;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullHttpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullHttpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIdsAreTracked();
|
||||
EnsureIsInitialized();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute to add a Friendly Name string with an UmbracoObjectType enum value
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
|
||||
internal class FriendlyNameAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// friendly name value
|
||||
/// </summary>
|
||||
private readonly string _friendlyName;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FriendlyNameAttribute class
|
||||
/// Sets the friendly name value
|
||||
/// </summary>
|
||||
/// <param name="friendlyName">attribute value</param>
|
||||
public FriendlyNameAttribute(string friendlyName)
|
||||
{
|
||||
this._friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the friendly name
|
||||
/// </summary>
|
||||
/// <returns>string of friendly name</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return this._friendlyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute to associate a GUID string and Type with an UmbracoObjectType Enum value
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class UmbracoObjectTypeAttribute : Attribute
|
||||
{
|
||||
public UmbracoObjectTypeAttribute(string objectId)
|
||||
{
|
||||
ObjectId = new Guid(objectId);
|
||||
}
|
||||
|
||||
public UmbracoObjectTypeAttribute(string objectId, Type modelType)
|
||||
{
|
||||
ObjectId = new Guid(objectId);
|
||||
ModelType = modelType;
|
||||
}
|
||||
|
||||
public Guid ObjectId { get; private set; }
|
||||
|
||||
public Type ModelType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A thread-safe representation of a <see cref="HashSet{T}"/>.
|
||||
/// Enumerating this collection is thread-safe and will only operate on a clone that is generated before returning the enumerator.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[Serializable]
|
||||
public class ConcurrentHashSet<T> : ICollection<T>
|
||||
{
|
||||
private readonly HashSet<T> _innerSet = new HashSet<T>();
|
||||
private readonly ReaderWriterLockSlim _instanceLocker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>1</filterpriority>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return GetThreadSafeClone().GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through a collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </returns>
|
||||
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
||||
public bool Remove(T item)
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
return _innerSet.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public int Count
|
||||
{
|
||||
get { return GetThreadSafeClone().Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, false.
|
||||
/// </returns>
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
||||
public void Add(T item)
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
_innerSet.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to add an item to the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryAdd(T item)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
if (clone.Contains(item)) return false;
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
//double check
|
||||
if (_innerSet.Contains(item)) return false;
|
||||
_innerSet.Add(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
|
||||
public void Clear()
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
_innerSet.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
|
||||
/// </returns>
|
||||
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return GetThreadSafeClone().Contains(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/> to an <see cref="T:System.Array"/>, starting at a specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/>. The array must have zero-based indexing.</param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference (Nothing in Visual Basic).</exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception><exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than the length of the <paramref name="array"/> -or- The number of elements in the source <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>.</exception>
|
||||
public void CopyTo(T[] array, int index)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
clone.CopyTo(array, index);
|
||||
}
|
||||
|
||||
private HashSet<T> GetThreadSafeClone()
|
||||
{
|
||||
HashSet<T> clone = null;
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
clone = new HashSet<T>(_innerSet, _innerSet.Comparer);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing. </param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins. </param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is null. </exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero. </exception><exception cref="T:System.ArgumentException"><paramref name="array"/> is multidimensional.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>. </exception><exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"/> cannot be cast automatically to the type of the destination <paramref name="array"/>. </exception><filterpriority>2</filterpriority>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
Array.Copy(clone.ToArray(), 0, array, index, clone.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// A case-insensitive configuration converter for enumerations.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the enumeration.</typeparam>
|
||||
public class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
|
||||
where T : struct
|
||||
{
|
||||
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException("data");
|
||||
|
||||
//return Enum.Parse(typeof(T), (string)data, true);
|
||||
|
||||
T value;
|
||||
if (Enum.TryParse((string)data, true, out value))
|
||||
return value;
|
||||
|
||||
throw new Exception(string.Format("\"{0}\" is not valid {1} value. Valid values are: {2}.",
|
||||
data, typeof(T).Name,
|
||||
string.Join(", ", Enum.GetValues(typeof(T)).Cast<T>())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the configuration key for a section or a group.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class ConfigurationKeyAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
|
||||
/// </summary>
|
||||
/// <param name="configurationKey">The configurationkey.</param>
|
||||
public ConfigurationKeyAttribute(string configurationKey)
|
||||
{
|
||||
ConfigurationKey = configurationKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration key.
|
||||
/// </summary>
|
||||
public string ConfigurationKey { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -42,15 +42,24 @@ namespace Umbraco.Core.Configuration
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// used for unit tests
|
||||
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
|
||||
/// </summary>
|
||||
internal static void ResetCache()
|
||||
private static void ResetInternal()
|
||||
{
|
||||
_reservedUrlsCache = null;
|
||||
_reservedPaths = null;
|
||||
_reservedUrls = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static void Reset()
|
||||
{
|
||||
ResetInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reserved urls from web.config.
|
||||
/// </summary>
|
||||
@@ -575,6 +584,16 @@ namespace Umbraco.Core.Configuration
|
||||
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
|
||||
}
|
||||
|
||||
public static bool RequestIsInUmbracoApplication(HttpContextBase context)
|
||||
{
|
||||
return context.Request.Path.ToLower().IndexOf(IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower()) > -1;
|
||||
}
|
||||
|
||||
public static bool RequestIsLiveEditRedirector(HttpContextBase context)
|
||||
{
|
||||
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether umbraco should force a secure (https) connection to the backoffice.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
// note - still must work on how to support read-only and ResetSection for collections
|
||||
// note - still must work on how to spread config over files (aka DeepConfig in v5)
|
||||
|
||||
/// <summary>
|
||||
/// Represents an Umbraco section within the configuration file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The requirement for these sections is to be read-only.</para>
|
||||
/// <para>However for unit tests purposes it is internally possible to override some values, and
|
||||
/// then calling <c>>ResetSection</c> should cancel these changes and bring the section back to
|
||||
/// what it was originally.</para>
|
||||
/// <para>The <c>UmbracoSettings.For{T}</c> method will return a section, either one that
|
||||
/// is in the configuration file, or a section that was created with default values.</para>
|
||||
/// </remarks>
|
||||
public abstract class UmbracoConfigurationSection : ConfigurationSection
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the section actually is in the configuration file.
|
||||
/// </summary>
|
||||
protected bool IsPresent { get { return ElementInformation.IsPresent; } }
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>>To be used in unit tests.</remarks>
|
||||
internal protected virtual void ResetSection()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,13 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Web.Security;
|
||||
using System.Xml;
|
||||
using System.Configuration;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
@@ -20,6 +23,8 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
//TODO: Re-enable logging !!!!
|
||||
|
||||
//TODO: We need to convert this to a real section, it's currently using HttpRuntime.Cache to detect cahnges, this is real poor, especially in a console app
|
||||
|
||||
/// <summary>
|
||||
/// The UmbracoSettings Class contains general settings information for the entire Umbraco instance based on information from the /config/umbracoSettings.config file
|
||||
/// </summary>
|
||||
@@ -52,15 +57,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
|
||||
/// </summary>
|
||||
internal static void ResetSetters()
|
||||
private static void ResetInternal()
|
||||
{
|
||||
_addTrailingSlash = null;
|
||||
_forceSafeAliases = null;
|
||||
_useLegacySchema = null;
|
||||
_useDomainPrefixes = null;
|
||||
_umbracoLibraryCacheDuration = null;
|
||||
_trySkipIisCustomErrors = null;
|
||||
SettingsFilePath = null;
|
||||
SettingsFilePath = null;
|
||||
}
|
||||
|
||||
internal const string TempFriendlyXmlChildContainerNodename = ""; // "children";
|
||||
@@ -132,7 +136,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
/// <param name="key">The xpath query to the specific node.</param>
|
||||
/// <returns>If found, it returns the specific configuration xml node.</returns>
|
||||
public static XmlNode GetKeyAsNode(string key)
|
||||
internal static XmlNode GetKeyAsNode(string key)
|
||||
{
|
||||
if (key == null)
|
||||
throw new ArgumentException("Key cannot be null");
|
||||
@@ -147,7 +151,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetKey(string key)
|
||||
internal static string GetKey(string key)
|
||||
{
|
||||
EnsureSettingsDocument();
|
||||
|
||||
@@ -184,7 +188,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if new directories are allowed otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UploadAllowDirectories
|
||||
internal static bool UploadAllowDirectories
|
||||
{
|
||||
get { return bool.Parse(GetKey("/settings/content/UploadAllowDirectories")); }
|
||||
}
|
||||
@@ -211,7 +215,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether logging is enabled in umbracoSettings.config (/settings/logging/enableLogging).
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if logging is enabled; otherwise, <c>false</c>.</value>
|
||||
public static bool EnableLogging
|
||||
internal static bool EnableLogging
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -226,7 +230,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether logging happens async.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if async logging is enabled; otherwise, <c>false</c>.</value>
|
||||
public static bool EnableAsyncLogging
|
||||
internal static bool EnableAsyncLogging
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -241,7 +245,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the assembly of an external logger that can be used to store log items in 3rd party systems
|
||||
/// </summary>
|
||||
public static string ExternalLoggerAssembly
|
||||
internal static string ExternalLoggerAssembly
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -253,7 +257,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the type of an external logger that can be used to store log items in 3rd party systems
|
||||
/// </summary>
|
||||
public static string ExternalLoggerType
|
||||
internal static string ExternalLoggerType
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -265,7 +269,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Long Audit Trail to external log too
|
||||
/// </summary>
|
||||
public static bool ExternalLoggerLogAuditTrail
|
||||
internal static bool ExternalLoggerLogAuditTrail
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -284,7 +288,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Keep user alive as long as they have their browser open? Default is true
|
||||
/// </summary>
|
||||
public static bool KeepUserLoggedIn
|
||||
internal static bool KeepUserLoggedIn
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -296,10 +300,36 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AuthCookieName
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = GetKey("/settings/security/authCookieName");
|
||||
if (string.IsNullOrEmpty(value) == false)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return "UMB_UCONTEXT";
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AuthCookieDomain
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = GetKey("/settings/security/authCookieDomain");
|
||||
if (string.IsNullOrEmpty(value) == false)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return FormsAuthentication.CookieDomain;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the experimental canvas (live) editing on the frontend of the website
|
||||
/// </summary>
|
||||
public static bool EnableCanvasEditing
|
||||
internal static bool EnableCanvasEditing
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -314,7 +344,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Show disabled users in the tree in the Users section in the backoffice
|
||||
/// </summary>
|
||||
public static bool HideDisabledUsersInBackoffice
|
||||
internal static bool HideDisabledUsersInBackoffice
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -330,7 +360,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether the logs will be auto cleaned
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if logs are to be automatically cleaned; otherwise, <c>false</c></value>
|
||||
public static bool AutoCleanLogs
|
||||
internal static bool AutoCleanLogs
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -345,7 +375,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the value indicating the log cleaning frequency (in miliseconds)
|
||||
/// </summary>
|
||||
public static int CleaningMiliseconds
|
||||
internal static int CleaningMiliseconds
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -357,7 +387,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
public static int MaxLogAge
|
||||
internal static int MaxLogAge
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -373,7 +403,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the disabled log types.
|
||||
/// </summary>
|
||||
/// <value>The disabled log types.</value>
|
||||
public static XmlNode DisabledLogTypes
|
||||
internal static XmlNode DisabledLogTypes
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/logging/disabledLogTypes"); }
|
||||
}
|
||||
@@ -382,7 +412,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the package server url.
|
||||
/// </summary>
|
||||
/// <value>The package server url.</value>
|
||||
public static string PackageServer
|
||||
internal static string PackageServer
|
||||
{
|
||||
get { return "packages.umbraco.org"; }
|
||||
}
|
||||
@@ -393,15 +423,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will use domain prefixes.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will use domain prefixes; otherwise, <c>false</c>.</value>
|
||||
// TODO rename as EnforceAbsoluteUrls
|
||||
public static bool UseDomainPrefixes
|
||||
internal static bool UseDomainPrefixes
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: false
|
||||
return _useDomainPrefixes ?? GetKeyValue("/settings/requestHandler/useDomainPrefixes", false);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_useDomainPrefixes = value;
|
||||
@@ -414,7 +443,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// This will add a trailing slash (/) to urls when in directory url mode
|
||||
/// NOTICE: This will always return false if Directory Urls in not active
|
||||
/// </summary>
|
||||
public static bool AddTrailingSlash
|
||||
internal static bool AddTrailingSlash
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -422,7 +451,7 @@ namespace Umbraco.Core.Configuration
|
||||
return GlobalSettings.UseDirectoryUrls
|
||||
&& (_addTrailingSlash ?? GetKeyValue("/settings/requestHandler/addTrailingSlash", false));
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_addTrailingSlash = value;
|
||||
@@ -433,7 +462,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will use ASP.NET MasterPages for rendering instead of its propriatary templating system.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will use ASP.NET MasterPages; otherwise, <c>false</c>.</value>
|
||||
public static bool UseAspNetMasterPages
|
||||
internal static bool UseAspNetMasterPages
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -455,7 +484,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether umbraco will attempt to load any skins to override default template files
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco will override templates with skins if present and configured <c>false</c>.</value>
|
||||
public static bool EnableTemplateFolders
|
||||
internal static bool EnableTemplateFolders
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -479,7 +508,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// razor DynamicNode typecasting detects XML and returns DynamicXml - Root elements that won't convert to DynamicXml
|
||||
/// </summary>
|
||||
public static IEnumerable<string> NotDynamicXmlDocumentElements
|
||||
internal static IEnumerable<string> NotDynamicXmlDocumentElements
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -503,7 +532,7 @@ namespace Umbraco.Core.Configuration
|
||||
private static IEnumerable<RazorDataTypeModelStaticMappingItem> _razorDataTypeModelStaticMapping;
|
||||
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
|
||||
|
||||
public static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
|
||||
internal static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -568,7 +597,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if umbraco will clone XML cache on publish; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool CloneXmlCacheOnPublish
|
||||
internal static bool CloneXmlCacheOnPublish
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -590,7 +619,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a value indicating whether rich text editor content should be parsed by tidy.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if content is parsed; otherwise, <c>false</c>.</value>
|
||||
public static bool TidyEditorContent
|
||||
internal static bool TidyEditorContent
|
||||
{
|
||||
get { return bool.Parse(GetKey("/settings/content/TidyEditorContent")); }
|
||||
}
|
||||
@@ -599,7 +628,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the encoding type for the tidyied content.
|
||||
/// </summary>
|
||||
/// <value>The encoding type as string.</value>
|
||||
public static string TidyCharEncoding
|
||||
internal static string TidyCharEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -616,12 +645,12 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the property context help option, this can either be 'text', 'icon' or 'none'
|
||||
/// </summary>
|
||||
/// <value>The property context help option.</value>
|
||||
public static string PropertyContextHelpOption
|
||||
internal static string PropertyContextHelpOption
|
||||
{
|
||||
get { return GetKey("/settings/content/PropertyContextHelpOption").ToLower(); }
|
||||
}
|
||||
|
||||
public static string DefaultBackofficeProvider
|
||||
internal static string DefaultBackofficeProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -638,37 +667,36 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Whether to force safe aliases (no spaces, no special characters) at businesslogic level on contenttypes and propertytypes
|
||||
/// </summary>
|
||||
public static bool ForceSafeAliases
|
||||
internal static bool ForceSafeAliases
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: true
|
||||
return _forceSafeAliases ?? GetKeyValue("/settings/content/ForceSafeAliases", true);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// used for unit testing
|
||||
_forceSafeAliases = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? _trySkipIisCustomErrors;
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to try to skip IIS custom errors.
|
||||
/// </summary>
|
||||
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.TrySkipIisCustomErrors instead.")]
|
||||
internal static bool TrySkipIisCustomErrors
|
||||
{
|
||||
get { return GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating where to try to skip IIS custom errors.
|
||||
/// Gets a value indicating whether internal redirect preserves the template.
|
||||
/// </summary>
|
||||
public static bool TrySkipIisCustomErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: false
|
||||
return _trySkipIisCustomErrors ?? GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false);
|
||||
}
|
||||
internal set
|
||||
{
|
||||
// used for unit testing
|
||||
_trySkipIisCustomErrors = value;
|
||||
}
|
||||
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.InternalRedirectPerservesTemplate instead.")]
|
||||
internal static bool InternalRedirectPreservesTemplate
|
||||
{
|
||||
get { return GetKeyValue("/settings/web.routing/@internalRedirectPreservesTemplate", false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -687,7 +715,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the allowed image file types.
|
||||
/// </summary>
|
||||
/// <value>The allowed image file types.</value>
|
||||
public static string ImageFileTypes
|
||||
internal static string ImageFileTypes
|
||||
{
|
||||
get { return GetKey("/settings/content/imaging/imageFileTypes").ToLowerInvariant(); }
|
||||
}
|
||||
@@ -696,7 +724,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the allowed script file types.
|
||||
/// </summary>
|
||||
/// <value>The allowed script file types.</value>
|
||||
public static string ScriptFileTypes
|
||||
internal static string ScriptFileTypes
|
||||
{
|
||||
get { return GetKey("/settings/content/scripteditor/scriptFileTypes"); }
|
||||
}
|
||||
@@ -707,14 +735,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the duration in seconds to cache queries to umbraco library member and media methods
|
||||
/// Default is 1800 seconds (30 minutes)
|
||||
/// </summary>
|
||||
public static int UmbracoLibraryCacheDuration
|
||||
internal static int UmbracoLibraryCacheDuration
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: 1800
|
||||
return _umbracoLibraryCacheDuration ?? GetKeyValue("/settings/content/UmbracoLibraryCacheDuration", 1800);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// for unit tests only
|
||||
_umbracoLibraryCacheDuration = value;
|
||||
@@ -725,7 +753,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the path to the scripts folder used by the script editor.
|
||||
/// </summary>
|
||||
/// <value>The script folder path.</value>
|
||||
public static string ScriptFolderPath
|
||||
internal static string ScriptFolderPath
|
||||
{
|
||||
get { return GetKey("/settings/content/scripteditor/scriptFolderPath"); }
|
||||
}
|
||||
@@ -733,7 +761,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Enabled or disable the script/code editor
|
||||
/// </summary>
|
||||
public static bool ScriptDisableEditor
|
||||
internal static bool ScriptDisableEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -751,7 +779,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// ex: existingnodename.aspx would become existingnodename(1).aspx if a node with the same name is found
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco ensures unique node naming; otherwise, <c>false</c>.</value>
|
||||
public static bool EnsureUniqueNaming
|
||||
internal static bool EnsureUniqueNaming
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -770,7 +798,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the notification email sender.
|
||||
/// </summary>
|
||||
/// <value>The notification email sender.</value>
|
||||
public static string NotificationEmailSender
|
||||
internal static string NotificationEmailSender
|
||||
{
|
||||
get { return GetKey("/settings/content/notifications/email"); }
|
||||
}
|
||||
@@ -781,7 +809,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if html notification-emails are disabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool NotificationDisableHtmlEmail
|
||||
internal static bool NotificationDisableHtmlEmail
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -794,12 +822,12 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the allowed attributes on images.
|
||||
/// </summary>
|
||||
/// <value>The allowed attributes on images.</value>
|
||||
public static string ImageAllowedAttributes
|
||||
internal static string ImageAllowedAttributes
|
||||
{
|
||||
get { return GetKey("/settings/content/imaging/allowedAttributes"); }
|
||||
}
|
||||
|
||||
public static XmlNode ImageAutoFillImageProperties
|
||||
internal static XmlNode ImageAutoFillImageProperties
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/content/imaging/autoFillImageProperties"); }
|
||||
}
|
||||
@@ -808,7 +836,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the scheduled tasks as XML
|
||||
/// </summary>
|
||||
/// <value>The scheduled tasks.</value>
|
||||
public static XmlNode ScheduledTasks
|
||||
internal static XmlNode ScheduledTasks
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/scheduledTasks"); }
|
||||
}
|
||||
@@ -817,7 +845,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets a list of characters that will be replaced when generating urls
|
||||
/// </summary>
|
||||
/// <value>The URL replacement characters.</value>
|
||||
public static XmlNode UrlReplaceCharacters
|
||||
internal static XmlNode UrlReplaceCharacters
|
||||
{
|
||||
get { return GetKeyAsNode("/settings/requestHandler/urlReplacing"); }
|
||||
}
|
||||
@@ -825,7 +853,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Whether to replace double dashes from url (ie my--story----from--dash.aspx caused by multiple url replacement chars
|
||||
/// </summary>
|
||||
public static bool RemoveDoubleDashesFromUrlReplacing
|
||||
internal static bool RemoveDoubleDashesFromUrlReplacing
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -846,7 +874,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Used for load-balancing high-traffic sites.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco uses distributed calls; otherwise, <c>false</c>.</value>
|
||||
public static bool UseDistributedCalls
|
||||
internal static bool UseDistributedCalls
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -866,7 +894,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the ID of the user with access rights to perform the distributed calls.
|
||||
/// </summary>
|
||||
/// <value>The distributed call user.</value>
|
||||
public static int DistributedCallUser
|
||||
internal static int DistributedCallUser
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -884,7 +912,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Gets the html injected into a (x)html page if Umbraco is running in preview mode
|
||||
/// </summary>
|
||||
public static string PreviewBadge
|
||||
internal static string PreviewBadge
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -905,7 +933,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// and update their content cache accordingly, ensuring a consistent cache on all servers
|
||||
/// </summary>
|
||||
/// <value>The distribution servers.</value>
|
||||
public static XmlNode DistributionServers
|
||||
internal static XmlNode DistributionServers
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -925,7 +953,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// A help page configuration specify language, user type, application, application url and
|
||||
/// the target help page url.
|
||||
/// </summary>
|
||||
public static XmlNode HelpPages
|
||||
internal static XmlNode HelpPages
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -947,7 +975,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// All packages installed from a repository gets the repository alias included in the install information
|
||||
/// </summary>
|
||||
/// <value>The repository servers.</value>
|
||||
public static XmlNode Repositories
|
||||
internal static XmlNode Repositories
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -970,7 +998,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if umbraco will use the viewstate mover module; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UseViewstateMoverModule
|
||||
internal static bool UseViewstateMoverModule
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -992,7 +1020,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Tells us whether the Xml Content cache is disabled or not
|
||||
/// Default is enabled
|
||||
/// </summary>
|
||||
public static bool IsXmlContentCacheDisabled
|
||||
internal static bool IsXmlContentCacheDisabled
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1017,7 +1045,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Makes it possible to updates environments by syncing the umbraco.config file across instances
|
||||
/// Relates to http://umbraco.codeplex.com/workitem/30722
|
||||
/// </summary>
|
||||
public static bool XmlContentCheckForDiskChanges
|
||||
internal static bool XmlContentCheckForDiskChanges
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1042,7 +1070,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// If disabled, only documents will generate data.
|
||||
/// This feature is useful if anyone would like to see how data looked at a given time
|
||||
/// </summary>
|
||||
public static bool EnableGlobalPreviewStorage
|
||||
internal static bool EnableGlobalPreviewStorage
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1070,14 +1098,14 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>
|
||||
/// <c>true</c> if yes, use the old node/data model; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public static bool UseLegacyXmlSchema
|
||||
internal static bool UseLegacyXmlSchema
|
||||
{
|
||||
get
|
||||
{
|
||||
// default: true
|
||||
return _useLegacySchema ?? GetKeyValue("/settings/content/UseLegacyXmlSchema", false);
|
||||
}
|
||||
internal set
|
||||
/*internal*/ set
|
||||
{
|
||||
// used for unit testing
|
||||
_useLegacySchema = value;
|
||||
@@ -1085,7 +1113,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
|
||||
public static IEnumerable<string> AppCodeFileExtensionsList
|
||||
internal static IEnumerable<string> AppCodeFileExtensionsList
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1096,7 +1124,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
[Obsolete("This setting is not used anymore, the only file extensions that are supported are .cs and .vb files")]
|
||||
public static XmlNode AppCodeFileExtensions
|
||||
internal static XmlNode AppCodeFileExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1118,7 +1146,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Tells us whether the Xml to always update disk cache, when changes are made to content
|
||||
/// Default is enabled
|
||||
/// </summary>
|
||||
public static bool ContinouslyUpdateXmlDiskCache
|
||||
internal static bool ContinouslyUpdateXmlDiskCache
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1144,7 +1172,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// have a splash page
|
||||
/// Default is disabled
|
||||
/// </summary>
|
||||
public static bool EnableSplashWhileLoading
|
||||
internal static bool EnableSplashWhileLoading
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1165,7 +1193,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
private static bool? _resolveUrlsFromTextString;
|
||||
public static bool ResolveUrlsFromTextString
|
||||
internal static bool ResolveUrlsFromTextString
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1202,7 +1230,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// is used instead of the masterpages editor
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if umbraco defaults to using MVC views for templating, otherwise <c>false</c>.</value>
|
||||
public static RenderingEngine DefaultRenderingEngine
|
||||
internal static RenderingEngine DefaultRenderingEngine
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1226,6 +1254,12 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
return _defaultRenderingEngine.Value;
|
||||
}
|
||||
//internal set
|
||||
//{
|
||||
// _defaultRenderingEngine = value;
|
||||
// var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode("/settings/templates/defaultRenderingEngine");
|
||||
// node.InnerText = value.ToString();
|
||||
//}
|
||||
}
|
||||
|
||||
private static MacroErrorBehaviour? _macroErrorBehaviour;
|
||||
@@ -1237,7 +1271,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
|
||||
/// </summary>
|
||||
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
|
||||
public static MacroErrorBehaviour MacroErrorBehaviour
|
||||
internal static MacroErrorBehaviour MacroErrorBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1272,7 +1306,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// - HideFileDuplicates - Show files in the sprite and hide duplicates on disk
|
||||
/// </summary>
|
||||
/// <value>MacroErrorBehaviour enum defining how to show icons in the document type editor.</value>
|
||||
public static IconPickerBehaviour IconPickerBehaviour
|
||||
internal static IconPickerBehaviour IconPickerBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -1298,6 +1332,25 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default document type property used when adding new properties through the back-office
|
||||
/// </summary>
|
||||
/// <value>Configured text for the default document type property</value>
|
||||
/// <remarks>If undefined, 'Textstring' is the default</remarks>
|
||||
public static string DefaultDocumentTypeProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
var defaultDocumentTypeProperty = GetKey("/settings/content/defaultDocumentTypeProperty");
|
||||
if (string.IsNullOrEmpty(defaultDocumentTypeProperty))
|
||||
{
|
||||
defaultDocumentTypeProperty = "Textstring";
|
||||
}
|
||||
|
||||
return defaultDocumentTypeProperty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration regarding webservices
|
||||
/// </summary>
|
||||
@@ -1481,6 +1534,80 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Extensible settings
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static void Reset()
|
||||
{
|
||||
ResetInternal();
|
||||
|
||||
using (new WriteLock(SectionsLock))
|
||||
{
|
||||
foreach (var section in Sections.Values)
|
||||
section.ResetSection();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ReaderWriterLockSlim SectionsLock = new ReaderWriterLockSlim();
|
||||
private static readonly Dictionary<Type, UmbracoConfigurationSection> Sections = new Dictionary<Type, UmbracoConfigurationSection>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified UmbracoConfigurationSection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the UmbracoConfigurationSectiont.</typeparam>
|
||||
/// <returns>The UmbracoConfigurationSection of the specified type.</returns>
|
||||
public static T For<T>()
|
||||
where T : UmbracoConfigurationSection, new()
|
||||
{
|
||||
var sectionType = typeof (T);
|
||||
using (new WriteLock(SectionsLock))
|
||||
{
|
||||
if (Sections.ContainsKey(sectionType)) return Sections[sectionType] as T;
|
||||
|
||||
var attr = sectionType.GetCustomAttribute<ConfigurationKeyAttribute>(false);
|
||||
if (attr == null)
|
||||
throw new InvalidOperationException(string.Format("Type \"{0}\" is missing attribute ConfigurationKeyAttribute.", sectionType.FullName));
|
||||
|
||||
var sectionKey = attr.ConfigurationKey;
|
||||
if (string.IsNullOrWhiteSpace(sectionKey))
|
||||
throw new InvalidOperationException(string.Format("Type \"{0}\" ConfigurationKeyAttribute value is null or empty.", sectionType.FullName));
|
||||
|
||||
var section = GetSection(sectionType, sectionKey);
|
||||
|
||||
Sections[sectionType] = section;
|
||||
return section as T;
|
||||
}
|
||||
}
|
||||
|
||||
private static UmbracoConfigurationSection GetSection(Type sectionType, string key)
|
||||
{
|
||||
if (!sectionType.Inherits<UmbracoConfigurationSection>())
|
||||
throw new ArgumentException(string.Format(
|
||||
"Type \"{0}\" does not inherit from UmbracoConfigurationSection.", sectionType.FullName), "sectionType");
|
||||
|
||||
var section = ConfigurationManager.GetSection(key);
|
||||
|
||||
if (section != null && section.GetType() != sectionType)
|
||||
throw new InvalidCastException(string.Format("Section at key \"{0}\" is of type \"{1}\" and not \"{2}\".",
|
||||
key, section.GetType().FullName, sectionType.FullName));
|
||||
|
||||
if (section != null) return section as UmbracoConfigurationSection;
|
||||
|
||||
section = Activator.CreateInstance(sectionType) as UmbracoConfigurationSection;
|
||||
|
||||
if (section == null)
|
||||
throw new NullReferenceException(string.Format(
|
||||
"Activator failed to create an instance of type \"{0}\" for key\"{1}\" and returned null.",
|
||||
sectionType.FullName, key));
|
||||
|
||||
return section as UmbracoConfigurationSection;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("6.0.4");
|
||||
private static readonly Version Version = new Version("6.1.6");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the alias identifiers for Umbraco's core application sections.
|
||||
/// </summary>
|
||||
public static class Applications
|
||||
{
|
||||
/// <summary>
|
||||
/// Application alias for the content section.
|
||||
/// </summary>
|
||||
public const string Content = "content";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the developer section.
|
||||
/// </summary>
|
||||
public const string Developer = "developer";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the media section.
|
||||
/// </summary>
|
||||
public const string Media = "media";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the members section.
|
||||
/// </summary>
|
||||
public const string Members = "member";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the settings section.
|
||||
/// </summary>
|
||||
public const string Settings = "settings";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the translation section.
|
||||
/// </summary>
|
||||
public const string Translation = "translation";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the users section.
|
||||
/// </summary>
|
||||
public const string Users = "users";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for property-type alias conventions that are used within the Umbraco core.
|
||||
/// </summary>
|
||||
public static class Conventions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Content property aliases.
|
||||
/// </summary>
|
||||
public static class Content
|
||||
{
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url (internal) redirect.
|
||||
/// </summary>
|
||||
public const string InternalRedirectId = "umbracoInternalRedirectId";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's navigational hide, (not actually used in core code).
|
||||
/// </summary>
|
||||
public const string NaviHide = "umbracoNaviHide";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url redirect.
|
||||
/// </summary>
|
||||
public const string Redirect = "umbracoRedirect";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url alias.
|
||||
/// </summary>
|
||||
public const string UrlAlias = "umbracoUrlAlias";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url name.
|
||||
/// </summary>
|
||||
public const string UrlName = "umbracoUrlName";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Media property aliases.
|
||||
/// </summary>
|
||||
public static class Media
|
||||
{
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file name.
|
||||
/// </summary>
|
||||
public const string File = "umbracoFile";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's width.
|
||||
/// </summary>
|
||||
public const string Width = "umbracoWidth";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's height.
|
||||
/// </summary>
|
||||
public const string Height = "umbracoHeight";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file size (in bytes).
|
||||
/// </summary>
|
||||
public const string Bytes = "umbracoBytes";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file extension.
|
||||
/// </summary>
|
||||
public const string Extension = "umbracoExtension";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the alias identifiers for Umbraco media types.
|
||||
/// </summary>
|
||||
public static class MediaTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// MediaType alias for a file.
|
||||
/// </summary>
|
||||
public const string File = "File";
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for an image.
|
||||
/// </summary>
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco URLs/Querystrings.
|
||||
/// </summary>
|
||||
public static class Url
|
||||
{
|
||||
/// <summary>
|
||||
/// Querystring parameter name used for Umbraco's alternative template functionality.
|
||||
/// </summary>
|
||||
public const string AltTemplate = "altTemplate";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco object types as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class ObjectTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for a Content Item object.
|
||||
/// </summary>
|
||||
public const string ContentItem = "10E2B09F-C28B-476D-B77A-AA686435E44A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Content Item Type object.
|
||||
/// </summary>
|
||||
public const string ContentItemType = "7A333C54-6F43-40A4-86A2-18688DC7E532";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Content Recycle Bin.
|
||||
/// </summary>
|
||||
public const string ContentRecycleBin = "01BB7FF2-24DC-4C0C-95A2-C24EF72BBAC8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a DataType object.
|
||||
/// </summary>
|
||||
public const string DataType = "30A2A501-1978-4DDB-A57B-F7EFED43BA3C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document object.
|
||||
/// </summary>
|
||||
public const string Document = "C66BA18E-EAF3-4CFF-8A22-41B16D66A972";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document Type object.
|
||||
/// </summary>
|
||||
public const string DocumentType = "A2CB7800-F571-4787-9638-BC48539A0EFB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media object.
|
||||
/// </summary>
|
||||
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Media Recycle Bin.
|
||||
/// </summary>
|
||||
public const string MediaRecycleBin = "CF3D8E34-1C1C-41e9-AE56-878B57B32113";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media Type object.
|
||||
/// </summary>
|
||||
public const string MediaType = "4EA4382B-2F5A-4C2B-9587-AE9B3CF3602E";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member object.
|
||||
/// </summary>
|
||||
public const string Member = "39EB0F98-B348-42A1-8662-E7EB18487560";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Group object.
|
||||
/// </summary>
|
||||
public const string MemberGroup = "366E63B9-880F-4E13-A61C-98069B029728";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Type object.
|
||||
/// </summary>
|
||||
public const string MemberType = "9B5416FB-E72F-45A9-A07B-5A9A2709CE43";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Stylesheet object.
|
||||
/// </summary>
|
||||
public const string Stylesheet = "9F68DA4F-A3A8-44C2-8226-DCBD125E4840";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the System Root.
|
||||
/// </summary>
|
||||
public const string SystemRoot = "EA7D8624-4CFE-4578-A871-24AA946BF34D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Template object.
|
||||
/// </summary>
|
||||
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco Property Editors as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for the Checkbox list datatype.
|
||||
/// </summary>
|
||||
public const string CheckBoxList = "B4471851-82B6-4C75-AFA4-39FA9C6A75E9";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Color Picker datatype.
|
||||
/// </summary>
|
||||
public const string ColorPicker = "F8D60F68-EC59-4974-B43B-C46EB5677985";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Content Picker datatype.
|
||||
/// </summary>
|
||||
public const string ContentPicker = "158AA029-24ED-4948-939E-C3DA209E5FBA";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Date datatype.
|
||||
/// </summary>
|
||||
public const string Date = "23E93522-3200-44E2-9F29-E61A6FCBB79A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Date/Time datatype.
|
||||
/// </summary>
|
||||
public const string DateTime = "B6FB1622-AFA5-4BBF-A3CC-D9672A442222";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dictionary Picker datatype.
|
||||
/// </summary>
|
||||
public const string DictionaryPicker = "17B70066-F764-407D-AB05-3717F1E1C513";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list datatype.
|
||||
/// </summary>
|
||||
public const string DropDownList = "A74EA9C9-8E18-4D2A-8CF6-73C6206C5DA6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list multiple datatype.
|
||||
/// </summary>
|
||||
public const string DropDownListMultiple = "928639ED-9C73-4028-920C-1E55DBB68783";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list multiple, publish keys datatype.
|
||||
/// </summary>
|
||||
public const string DropdownlistMultiplePublishKeys = "928639AA-9C73-4028-920C-1E55DBB68783";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list, publishing keys datatype.
|
||||
/// </summary>
|
||||
public const string DropdownlistPublishingKeys = "A74EA9E1-8E18-4D2A-8CF6-73C6206C5DA6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Folder browser datatype.
|
||||
/// </summary>
|
||||
public const string FolderBrowser = "CCCD4AE9-F399-4ED2-8038-2E88D19E810C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Image Cropper datatype.
|
||||
/// </summary>
|
||||
public const string ImageCropper = "7A2D436C-34C2-410F-898F-4A23B3D79F54";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Integer datatype.
|
||||
/// </summary>
|
||||
public const string Integer = "1413AFCB-D19A-4173-8E9A-68288D2A73B8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Macro Container datatype.
|
||||
/// </summary>
|
||||
public const string MacroContainer = "474FCFF8-9D2D-11DE-ABC6-AD7A56D89593";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Media Picker datatype.
|
||||
/// </summary>
|
||||
public const string MediaPicker = "EAD69342-F06D-4253-83AC-28000225583B";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Member Picker datatype.
|
||||
/// </summary>
|
||||
public const string MemberPicker = "39F533E4-0551-4505-A64B-E0425C5CE775";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multi-Node Tree Picker datatype
|
||||
/// </summary>
|
||||
public const string MultiNodeTreePicker = "7E062C13-7C41-4AD9-B389-41D88AEEF87C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multiple Textstring datatype.
|
||||
/// </summary>
|
||||
public const string MultipleTextstring = "5359AD0B-06CC-4182-92BD-0A9117448D3F";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the No edit datatype.
|
||||
/// </summary>
|
||||
public const string NoEdit = "6C738306-4C17-4D88-B9BD-6546F3771597";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Picker Relations datatype.
|
||||
/// </summary>
|
||||
public const string PickerRelations = "83396FF2-2E39-4A90-9066-17F5F3989374";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Radiobutton list datatype.
|
||||
/// </summary>
|
||||
public const string RadioButtonList = "A52C7C1C-C330-476E-8605-D63D3B84B6A6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Related Links datatype.
|
||||
/// </summary>
|
||||
public const string RelatedLinks = "71B8AD1A-8DC2-425C-B6B8-FAA158075E63";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Slider datatype.
|
||||
/// </summary>
|
||||
public const string Slider = "29E790E6-26B3-438A-B21F-908663A0B19E";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Tags datatype.
|
||||
/// </summary>
|
||||
public const string Tags = "4023E540-92F5-11DD-AD8B-0800200C9A66";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Textbox datatype.
|
||||
/// </summary>
|
||||
public const string Textbox = "EC15C1E5-9D90-422A-AA52-4F7622C63BEA";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Textbox multiple datatype.
|
||||
/// </summary>
|
||||
public const string TextboxMultiple = "67DB8357-EF57-493E-91AC-936D305E0F2A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the TinyMCE v3 wysiwyg datatype.
|
||||
/// </summary>
|
||||
public const string TinyMCEv3 = "5E9B75AE-FACE-41C8-B47E-5F4B0FD82F83";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the TinyMCE wysiwyg (deprecated, upgrade to tinymce v3!) datatype.
|
||||
/// </summary>
|
||||
public const string TinyMCE = "83722133-F80C-4273-BDB6-1BEFAA04A612";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the True/False (Ja/Nej) datatype.
|
||||
/// </summary>
|
||||
public const string TrueFalse = "38B352C1-E9F8-4FD8-9324-9A2EAB06D97A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Ultimate Picker datatype.
|
||||
/// </summary>
|
||||
public const string UltimatePicker = "CDBF0B5D-5CB2-445F-BC12-FCAAEC07CF2C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the UltraSimpleEditor datatype.
|
||||
/// </summary>
|
||||
public const string UltraSimpleEditor = "60B7DABF-99CD-41EB-B8E9-4D2E669BBDE9";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Umbraco Usercontrol Wrapper datatype.
|
||||
/// </summary>
|
||||
public const string UmbracoUserControlWrapper = "D15E1281-E456-4B24-AA86-1DDA3E4299D5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Upload field datatype.
|
||||
/// </summary>
|
||||
public const string UploadField = "5032A6E6-69E3-491D-BB28-CD31CD11086C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the XPath CheckBoxList datatype.
|
||||
/// </summary>
|
||||
public const string XPathCheckBoxList = "34451D92-D270-49BA-8C7F-EE55BFEEE1CB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the XPath DropDownList datatype.
|
||||
/// </summary>
|
||||
public const string XPathDropDownList = "173A96AE-00ED-4A7C-9F76-4B53D4A0A1B9";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco system nodes.
|
||||
/// </summary>
|
||||
public static class System
|
||||
{
|
||||
/// <summary>
|
||||
/// The integer identifier for global system root node.
|
||||
/// </summary>
|
||||
public const int Root = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The integer identifier for content's recycle bin.
|
||||
/// </summary>
|
||||
public const int RecycleBinContent = -20;
|
||||
|
||||
/// <summary>
|
||||
/// The integer identifier for media's recycle bin.
|
||||
/// </summary>
|
||||
public const int RecycleBinMedia = -21;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants all the identifiers within the Umbraco core.
|
||||
/// </summary>
|
||||
public static partial class Constants
|
||||
{
|
||||
// generic constants can go here
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,13 @@ using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSix;
|
||||
using Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixZeroOne;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core.Strings;
|
||||
using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -49,8 +53,9 @@ namespace Umbraco.Core
|
||||
if (_isInitialized)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
|
||||
LogHelper.Info<CoreBootManager>("Umbraco application starting");
|
||||
_timer = DisposableTimer.Start(x => LogHelper.Info<CoreBootManager>("Umbraco application startup complete" + " (took " + x + "ms)"));
|
||||
InitializeProfilerResolver();
|
||||
|
||||
_timer = DisposableTimer.DebugDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
|
||||
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
|
||||
@@ -90,6 +95,20 @@ namespace Umbraco.Core
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ProfilerResolver
|
||||
/// </summary>
|
||||
protected virtual void InitializeProfilerResolver()
|
||||
{
|
||||
//By default we'll initialize the Log profiler (in the web project, we'll override with the web profiler)
|
||||
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler())
|
||||
{
|
||||
//This is another special resolver that needs to be resolvable before resolution is frozen
|
||||
//since it is used for profiling the application startup
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ApplicationEventsResolver and any modifications required for it such
|
||||
/// as adding custom types to the resolver.
|
||||
@@ -106,6 +125,19 @@ namespace Umbraco.Core
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
//add custom types here that are internal
|
||||
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to extend the use of Umbraco by enabling the consumer to overwrite
|
||||
/// the absolute path to the root of an Umbraco site/solution, which is used for stuff
|
||||
/// like Umbraco.Core.IO.IOHelper.MapPath etc.
|
||||
/// </summary>
|
||||
/// <param name="rootPath">Absolute</param>
|
||||
protected virtual void InitializeApplicationRootPath(string rootPath)
|
||||
{
|
||||
Umbraco.Core.IO.IOHelper.SetRootDirectory(rootPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -153,7 +185,7 @@ namespace Umbraco.Core
|
||||
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
|
||||
|
||||
//Now, startup all of our legacy startup handler
|
||||
ApplicationEventsResolver.Current.InstantiateLegacyStartupHanlders();
|
||||
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
|
||||
|
||||
if (afterComplete != null)
|
||||
{
|
||||
@@ -175,12 +207,26 @@ namespace Umbraco.Core
|
||||
{
|
||||
Resolution.Freeze();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
{
|
||||
|
||||
//by default we'll use the standard configuration based sync
|
||||
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
|
||||
new ConfigServerRegistrar());
|
||||
|
||||
//by default (outside of the web) we'll use the default server messenger without
|
||||
//supplying a username/password, this will automatically disable distributed calls
|
||||
// .. we'll override this in the WebBootManager
|
||||
ServerMessengerResolver.Current = new ServerMessengerResolver(
|
||||
new DefaultServerMessenger());
|
||||
|
||||
MappingResolver.Current = new MappingResolver(
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
|
||||
@@ -205,30 +251,11 @@ namespace Umbraco.Core
|
||||
ActionsResolver.Current = new ActionsResolver(
|
||||
() => PluginManager.Current.ResolveActions());
|
||||
|
||||
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
|
||||
PluginManager.Current.ResolveMacroPropertyTypes());
|
||||
|
||||
//TODO: Y U NO WORK?
|
||||
//MigrationResolver.Current = new MigrationResolver(
|
||||
// PluginManager.Current.ResolveMigrationTypes());
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
() => PluginManager.Current.ResolveMigrationTypes());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (MigrationsVersionFourNineZero.RemoveUmbracoAppConstraints),
|
||||
typeof (DeleteAppTables),
|
||||
typeof (EnsureAppsTreesUpdated),
|
||||
typeof (MoveMasterContentTypeData),
|
||||
typeof (NewCmsContentType2ContentTypeTable),
|
||||
typeof (RemoveMasterContentTypeColumn),
|
||||
typeof (RenameCmsTabTable),
|
||||
typeof (RenameTabIdColumn),
|
||||
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
|
||||
typeof (UpdateCmsContentTypeTable),
|
||||
typeof (UpdateCmsContentVersionTable),
|
||||
typeof (UpdateCmsPropertyTypeGroupTable),
|
||||
typeof (UpdatePropertyTypesAndGroups)
|
||||
});
|
||||
|
||||
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
@@ -236,6 +263,18 @@ namespace Umbraco.Core
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
|
||||
}
|
||||
|
||||
// this is how we'd switch over to DefaultShortStringHelper _and_ still use
|
||||
// UmbracoSettings UrlReplaceCharacters...
|
||||
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
// new DefaultShortStringHelper().WithConfig(DefaultShortStringHelper.ApplyUrlReplaceCharacters));
|
||||
|
||||
// use the Legacy one for now
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
new LegacyShortStringHelper());
|
||||
|
||||
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
||||
typeof (DefaultUrlSegmentProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIdsAreTracked();
|
||||
EnsureIsInitialized();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Umbraco.Core
|
||||
public void ConfigureEmbeddedDatabaseConnection()
|
||||
{
|
||||
const string providerName = "System.Data.SqlServerCe.4.0";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf";
|
||||
const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;";
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
|
||||
@@ -169,6 +169,20 @@ namespace Umbraco.Core
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures a ConnectionString for the Umbraco database that uses Microsoft SQL Server integrated security.
|
||||
/// </summary>
|
||||
/// <param name="server">Name or address of the database server</param>
|
||||
/// <param name="databaseName">Name of the database</param>
|
||||
public void ConfigureIntegratedSecurityDatabaseConnection(string server, string databaseName)
|
||||
{
|
||||
const string providerName = "System.Data.SqlClient";
|
||||
string connectionString = String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
|
||||
{
|
||||
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
|
||||
@@ -282,16 +296,15 @@ namespace Umbraco.Core
|
||||
if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false)
|
||||
{
|
||||
var providerName = "System.Data.SqlClient";
|
||||
string connString = null;
|
||||
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName))
|
||||
{
|
||||
providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
|
||||
|
||||
_connectionString =
|
||||
ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
|
||||
|
||||
connString = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
|
||||
}
|
||||
Initialize(providerName, connString);
|
||||
|
||||
Initialize(providerName);
|
||||
DetermineSqlServerVersion();
|
||||
}
|
||||
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
|
||||
{
|
||||
@@ -328,6 +341,8 @@ namespace Umbraco.Core
|
||||
|
||||
//Remove the legacy connection string, so we don't end up in a loop if something goes wrong.
|
||||
GlobalSettings.RemoveSetting(GlobalSettings.UmbracoConnectionName);
|
||||
|
||||
DetermineSqlServerVersion();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -355,6 +370,55 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
internal void Initialize(string providerName, string connectionString)
|
||||
{
|
||||
_connectionString = connectionString;
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the lazy resolution of determining the SQL server version if that is the db type we're using
|
||||
/// </summary>
|
||||
private void DetermineSqlServerVersion()
|
||||
{
|
||||
|
||||
var sqlServerSyntax = SqlSyntaxContext.SqlSyntaxProvider as SqlServerSyntaxProvider;
|
||||
if (sqlServerSyntax != null)
|
||||
{
|
||||
//this will not execute now, it is lazy so will only execute when we need to actually know
|
||||
// the sql server version.
|
||||
sqlServerSyntax.VersionName = new Lazy<SqlServerVersionName>(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var database = this._factory.CreateDatabase();
|
||||
|
||||
var version = database.ExecuteScalar<string>("SELECT SERVERPROPERTY('productversion')");
|
||||
var firstPart = version.Split('.')[0];
|
||||
switch (firstPart)
|
||||
{
|
||||
case "11":
|
||||
return SqlServerVersionName.V2012;
|
||||
case "10":
|
||||
return SqlServerVersionName.V2008;
|
||||
case "9":
|
||||
return SqlServerVersionName.V2005;
|
||||
case "8":
|
||||
return SqlServerVersionName.V2000;
|
||||
case "7":
|
||||
return SqlServerVersionName.V7;
|
||||
default:
|
||||
return SqlServerVersionName.Other;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return SqlServerVersionName.Invalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
internal DatabaseSchemaResult ValidateDatabaseSchema()
|
||||
{
|
||||
if (_configured == false || (string.IsNullOrEmpty(_connectionString) || string.IsNullOrEmpty(ProviderName)))
|
||||
@@ -393,8 +457,8 @@ namespace Umbraco.Core
|
||||
if (supportsCaseInsensitiveQueries == false)
|
||||
{
|
||||
message = "<p> </p><p>The database you're trying to use does not support case insensitive queries. <br />We currently do not support these types of databases.</p>" +
|
||||
"<p>You can fix this by changing the following two settings in your my.ini file in your MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1\nlower_case_file_system=1</pre><br />" +
|
||||
"<p>You can fix this by changing the following setting in your my.ini file in your MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1</pre><br />" +
|
||||
"<p>Note: Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
|
||||
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
|
||||
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
|
||||
@@ -404,8 +468,8 @@ namespace Umbraco.Core
|
||||
else if (supportsCaseInsensitiveQueries == null)
|
||||
{
|
||||
message = "<p> </p><p>Warning! Could not check if your database type supports case insensitive queries. <br />We currently do not support these databases that do not support case insensitive queries.</p>" +
|
||||
"<p>You can check this by looking for the following two settings in your my.ini file in your MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1\nlower_case_file_system=1</pre><br />" +
|
||||
"<p>You can check this by looking for the following setting in your my.ini file in your MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1</pre><br />" +
|
||||
"<p>Note: Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
|
||||
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
|
||||
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
|
||||
@@ -418,8 +482,8 @@ namespace Umbraco.Core
|
||||
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
|
||||
"<p>However, your hosting provider may not support this option. Umbraco does not currently support MySQL installs that do not support case insensitive queries</p>" +
|
||||
"<p>Make sure to check with your hosting provider if they support case insensitive queries as well.</p>" +
|
||||
"<p>They can check this by looking for the following two settings in the my.ini file in their MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1\nlower_case_file_system=1</pre><br />" +
|
||||
"<p>They can check this by looking for the following setting in the my.ini file in their MySQL installation directory:</p>" +
|
||||
"<pre>lower_case_table_names=1</pre><br />" +
|
||||
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
|
||||
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
|
||||
}
|
||||
@@ -446,6 +510,8 @@ namespace Umbraco.Core
|
||||
message = message + "<p>Upgrade completed!</p>";
|
||||
}
|
||||
|
||||
//now that everything is done, we need to determine the version of SQL server that is executing
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
|
||||
return new Result { Message = message, Success = true, Percentage = "100" };
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static class DateTimeExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns the DateTime as an ISO formatted string that is globally expectable
|
||||
/// </summary>
|
||||
/// <param name="dt"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToIsoString(this DateTime dt)
|
||||
{
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
@@ -10,10 +11,60 @@ using System.Web;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
///<summary>
|
||||
/// Extension methods for dictionary
|
||||
/// Extension methods for dictionary & concurrentdictionary
|
||||
///</summary>
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="updateFactory"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Taken from: http://stackoverflow.com/questions/12240219/is-there-a-way-to-use-concurrentdictionary-tryupdate-with-a-lambda-expression
|
||||
///
|
||||
/// If there is an item in the dictionary with the key, it will keep trying to update it until it can
|
||||
/// </remarks>
|
||||
public static bool TryUpdate<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TValue, TValue> updateFactory)
|
||||
{
|
||||
TValue curValue;
|
||||
while (dict.TryGetValue(key, out curValue))
|
||||
{
|
||||
if (dict.TryUpdate(key, updateFactory(curValue), curValue))
|
||||
return true;
|
||||
//if we're looping either the key was removed by another thread, or another thread
|
||||
//changed the value, so we start again.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates an item with the specified key with the specified value
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="dict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="updateFactory"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Taken from: http://stackoverflow.com/questions/12240219/is-there-a-way-to-use-concurrentdictionary-tryupdate-with-a-lambda-expression
|
||||
///
|
||||
/// WARNING: If the value changes after we've retreived it, then the item will not be updated
|
||||
/// </remarks>
|
||||
public static bool TryUpdateOptimisitic<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, TKey key, Func<TValue, TValue> updateFactory)
|
||||
{
|
||||
TValue curValue;
|
||||
if (!dict.TryGetValue(key, out curValue))
|
||||
return false;
|
||||
dict.TryUpdate(key, updateFactory(curValue), curValue);
|
||||
return true;//note we return true whether we succeed or not, see explanation below.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary to another type by only using direct casting
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Profiling;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -9,11 +11,17 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
///
|
||||
/// using (DisposableTimer.TraceDuration{MyType}("starting", "finished"))
|
||||
/// {
|
||||
/// Thread.Sleep(567);
|
||||
/// }
|
||||
///
|
||||
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
|
||||
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
|
||||
// {
|
||||
// Thread.Sleep(567);
|
||||
// }
|
||||
/// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
|
||||
/// {
|
||||
/// Thread.Sleep(567);
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class DisposableTimer : DisposableObject
|
||||
@@ -24,7 +32,7 @@ namespace Umbraco.Core
|
||||
protected DisposableTimer(Action<long> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch
|
||||
{
|
||||
@@ -36,96 +44,149 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback.</param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use either TraceDuration or DebugDuration instead of using Start")]
|
||||
public static DisposableTimer Start(Action<long> callback)
|
||||
{
|
||||
return new DisposableTimer(callback);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
#region TraceDuration
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var startMsg = startMessage();
|
||||
LogHelper.Info(loggerType, startMsg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMsg);
|
||||
var profiler = ActivateProfiler(loggerType, startMsg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMsg);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
#region DebugDuration
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var msg = startMessage();
|
||||
LogHelper.Debug(loggerType, msg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, msg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
|
||||
@@ -134,5 +195,19 @@ namespace Umbraco.Core
|
||||
{
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
private static IDisposable ActivateProfiler(Type loggerType, string profileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ProfilerResolver.Current.Profiler.Step(loggerType, profileName);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
//swallow this exception, it will occur if the ProfilerResolver is not initialized... generally only in
|
||||
// unit tests.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Events
|
||||
{
|
||||
public class RecycleBinEventArgs : CancellableEventArgs
|
||||
{
|
||||
public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable<int> ids, List<string> files, bool emptiedSuccessfully)
|
||||
: base(false)
|
||||
{
|
||||
NodeObjectType = nodeObjectType;
|
||||
Ids = ids;
|
||||
Files = files;
|
||||
RecycleBinEmptiedSuccessfully = emptiedSuccessfully;
|
||||
}
|
||||
|
||||
public RecycleBinEventArgs(Guid nodeObjectType, IEnumerable<int> ids, List<string> files)
|
||||
: base(true)
|
||||
{
|
||||
NodeObjectType = nodeObjectType;
|
||||
Ids = ids;
|
||||
Files = files;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Id of the node object type of the items
|
||||
/// being deleted from the Recycle Bin.
|
||||
/// </summary>
|
||||
public Guid NodeObjectType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of Ids for each of the items being deleted from the Recycle Bin.
|
||||
/// </summary>
|
||||
public IEnumerable<int> Ids { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of Files that should be deleted as part
|
||||
/// of emptying the Recycle Bin.
|
||||
/// </summary>
|
||||
public List<string> Files { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether the Recycle Bin was emptied successfully
|
||||
/// </summary>
|
||||
public bool RecycleBinEmptiedSuccessfully { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this event was fired for the Content's Recycle Bin.
|
||||
/// </summary>
|
||||
public bool IsContentRecycleBin
|
||||
{
|
||||
get { return NodeObjectType == new Guid(Constants.ObjectTypes.Document); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this event was fired for the Media's Recycle Bin.
|
||||
/// </summary>
|
||||
public bool IsMediaRecycleBin
|
||||
{
|
||||
get { return NodeObjectType == new Guid(Constants.ObjectTypes.Media); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Custom IApplicationStartupHandler that auto subscribes to the applications events
|
||||
/// </summary>
|
||||
public interface IApplicationEventHandler : IApplicationStartupHandler
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Any class implementing this interface that is added to the httpcontext.items keys or values will be disposed of at the end of the request.
|
||||
/// </summary>
|
||||
public interface IDisposeOnRequestEnd : IDisposable
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,11 @@ using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class FileSystemProviderAttribute : Attribute
|
||||
public class FileSystemProviderAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
public string Alias { get; private set; }
|
||||
|
||||
public FileSystemProviderAttribute(string alias)
|
||||
{
|
||||
|
||||
+1
-2
@@ -6,8 +6,7 @@ using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProvider
|
||||
internal class FileSystemProviderConstants
|
||||
{
|
||||
public const string Media = "media";
|
||||
}
|
||||
@@ -9,9 +9,8 @@ using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProviderManager
|
||||
{
|
||||
public class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
|
||||
@@ -28,7 +27,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#region Constructors
|
||||
|
||||
public FileSystemProviderManager()
|
||||
internal FileSystemProviderManager()
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("FileSystemProviders");
|
||||
}
|
||||
@@ -48,7 +47,15 @@ namespace Umbraco.Core.IO
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
private readonly ConcurrentDictionary<Type, string> _wrappedProviderLookup = new ConcurrentDictionary<Type, string>();
|
||||
|
||||
public IFileSystem GetFileSystemProvider(string alias)
|
||||
/// <summary>
|
||||
/// Returns the underlying (non-typed) file system provider for the alias specified
|
||||
/// </summary>
|
||||
/// <param name="alias"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// It is recommended to use the typed GetFileSystemProvider method instead to get a strongly typed provider instance.
|
||||
/// </remarks>
|
||||
public IFileSystem GetUnderlyingFileSystemProvider(string alias)
|
||||
{
|
||||
//either get the constructor info from cache or create it and add to cache
|
||||
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
|
||||
@@ -88,6 +95,11 @@ namespace Umbraco.Core.IO
|
||||
return fs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the strongly typed file system provider
|
||||
/// </summary>
|
||||
/// <typeparam name="TProviderTypeFilter"></typeparam>
|
||||
/// <returns></returns>
|
||||
public TProviderTypeFilter GetFileSystemProvider<TProviderTypeFilter>()
|
||||
where TProviderTypeFilter : FileSystemWrapper
|
||||
{
|
||||
@@ -111,7 +123,7 @@ namespace Umbraco.Core.IO
|
||||
return attr.Alias;
|
||||
});
|
||||
|
||||
var innerFs = GetFileSystemProvider(alias);
|
||||
var innerFs = GetUnderlyingFileSystemProvider(alias);
|
||||
var outputFs = Activator.CreateInstance(typeof (TProviderTypeFilter), innerFs);
|
||||
return (TProviderTypeFilter)outputFs;
|
||||
}
|
||||
|
||||
+118
-86
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
@@ -37,7 +34,7 @@ namespace Umbraco.Core.IO
|
||||
if (virtualPath.StartsWith("~"))
|
||||
retval = virtualPath.Replace("~", SystemDirectories.Root);
|
||||
|
||||
if (virtualPath.StartsWith("/") && !virtualPath.StartsWith(SystemDirectories.Root))
|
||||
if (virtualPath.StartsWith("/") && virtualPath.StartsWith(SystemDirectories.Root) == false)
|
||||
retval = SystemDirectories.Root + "/" + virtualPath.TrimStart('/');
|
||||
|
||||
return retval;
|
||||
@@ -48,6 +45,8 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
if (virtualPath.StartsWith("~"))
|
||||
return virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/");
|
||||
else if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute))
|
||||
return virtualPath;
|
||||
else
|
||||
return VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root);
|
||||
}
|
||||
@@ -68,11 +67,7 @@ namespace Umbraco.Core.IO
|
||||
if (tag.Groups[1].Success)
|
||||
url = tag.Groups[1].Value;
|
||||
|
||||
// The richtext editor inserts a slash in front of the url. That's why we need this little fix
|
||||
// if (url.StartsWith("/"))
|
||||
// text = text.Replace(url, ResolveUrl(url.Substring(1)));
|
||||
// else
|
||||
if (!String.IsNullOrEmpty(url))
|
||||
if (string.IsNullOrEmpty(url) == false)
|
||||
{
|
||||
string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url);
|
||||
text = text.Replace(url, resolvedUrl);
|
||||
@@ -97,19 +92,15 @@ namespace Umbraco.Core.IO
|
||||
if (useHttpContext && HttpContext.Current != null)
|
||||
{
|
||||
//string retval;
|
||||
if (!string.IsNullOrEmpty(path) && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root)))
|
||||
if (string.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root)))
|
||||
return System.Web.Hosting.HostingEnvironment.MapPath(path);
|
||||
else
|
||||
return System.Web.Hosting.HostingEnvironment.MapPath("~/" + path.TrimStart('/'));
|
||||
}
|
||||
|
||||
//var root = (!string.IsNullOrEmpty(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath))
|
||||
// ? System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath.TrimEnd(IOHelper.DirSepChar)
|
||||
// : getRootDirectorySafe();
|
||||
|
||||
var root = GetRootDirectorySafe();
|
||||
var newPath = path.TrimStart('~', '/').Replace('/', IOHelper.DirSepChar);
|
||||
var retval = root + IOHelper.DirSepChar.ToString() + newPath;
|
||||
var retval = root + IOHelper.DirSepChar.ToString(CultureInfo.InvariantCulture) + newPath;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -137,51 +128,98 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates if the current filepath matches a directory where the user is allowed to edit a file
|
||||
/// Verifies that the current filepath matches a directory where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">filepath </param>
|
||||
/// <param name="validDir"></param>
|
||||
/// <returns>true if valid, throws a FileSecurityException if not</returns>
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDir">The valid directory.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (validDir.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
if (!filePath.StartsWith(validDir))
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return filePath.StartsWith(validDir);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the current filepath matches a directory where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDir">The valid directory.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (VerifyEditPath(filePath, validDir) == false)
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
/// <summary>
|
||||
/// Verifies that the current filepath matches one of several directories where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDirs">The valid directories.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
foreach (var dir in validDirs)
|
||||
{
|
||||
var validDir = dir;
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (validDir.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
if (filePath.StartsWith(validDir))
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
/// <summary>
|
||||
/// Validates that the current filepath matches one of several directories where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDirs">The valid directories.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
if (VerifyEditPath(filePath, validDirs) == false)
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the current filepath has one of several authorized extensions.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validFileExtensions">The valid extensions.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (filePath.StartsWith(MapPath(SystemDirectories.Root)) == false)
|
||||
filePath = MapPath(filePath);
|
||||
var f = new FileInfo(filePath);
|
||||
|
||||
return validFileExtensions.Contains(f.Extension.Substring(1));
|
||||
}
|
||||
|
||||
|
||||
if (!validFileExtensions.Contains(f.Extension.Substring(1)))
|
||||
/// <summary>
|
||||
/// Validates that the current filepath has one of several authorized extensions.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validFileExtensions">The valid extensions.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (VerifyFileExtension(filePath, validFileExtensions) == false)
|
||||
throw new FileSecurityException(String.Format("The extension for the current file '{0}' is not of an allowed type for this editor. This is typically controlled from either the installed MacroEngines or based on configuration in /config/umbracoSettings.config", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -194,7 +232,7 @@ namespace Umbraco.Core.IO
|
||||
/// <returns></returns>
|
||||
internal static string GetRootDirectorySafe()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_rootDir))
|
||||
if (string.IsNullOrEmpty(_rootDir) == false)
|
||||
{
|
||||
return _rootDir;
|
||||
}
|
||||
@@ -203,12 +241,53 @@ namespace Umbraco.Core.IO
|
||||
var uri = new Uri(codeBase);
|
||||
var path = uri.LocalPath;
|
||||
var baseDirectory = Path.GetDirectoryName(path);
|
||||
_rootDir = baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin") - 1);
|
||||
if (string.IsNullOrEmpty(baseDirectory))
|
||||
throw new Exception("No root directory could be resolved. Please ensure that your Umbraco solution is correctly configured.");
|
||||
|
||||
_rootDir = baseDirectory.Contains("bin")
|
||||
? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1)
|
||||
: baseDirectory;
|
||||
|
||||
return _rootDir;
|
||||
|
||||
}
|
||||
|
||||
internal static string GetRootDirectoryBinFolder()
|
||||
{
|
||||
string binFolder = string.Empty;
|
||||
if (string.IsNullOrEmpty(_rootDir))
|
||||
{
|
||||
binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory.FullName;
|
||||
return binFolder;
|
||||
}
|
||||
|
||||
binFolder = Path.Combine(GetRootDirectorySafe(), "bin");
|
||||
|
||||
#if DEBUG
|
||||
var debugFolder = Path.Combine(binFolder, "debug");
|
||||
if (Directory.Exists(debugFolder))
|
||||
return debugFolder;
|
||||
#endif
|
||||
var releaseFolder = Path.Combine(binFolder, "release");
|
||||
if (Directory.Exists(releaseFolder))
|
||||
return releaseFolder;
|
||||
|
||||
if (Directory.Exists(binFolder))
|
||||
return binFolder;
|
||||
|
||||
return _rootDir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to overwrite RootDirectory, which would otherwise be resolved
|
||||
/// automatically upon application start.
|
||||
/// </summary>
|
||||
/// <remarks>The supplied path should be the absolute path to the root of the umbraco site.</remarks>
|
||||
/// <param name="rootPath"></param>
|
||||
internal static void SetRootDirectory(string rootPath)
|
||||
{
|
||||
_rootDir = rootPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if filename passed has any special chars in it and strips them to create a safe filename. Used to overcome an issue when Umbraco is used in IE in an intranet environment.
|
||||
/// </summary>
|
||||
@@ -216,55 +295,8 @@ namespace Umbraco.Core.IO
|
||||
/// <returns>A safe filename without any path specific chars.</returns>
|
||||
internal static string SafeFileName(string filePath)
|
||||
{
|
||||
if (String.IsNullOrEmpty(filePath))
|
||||
return String.Empty;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
foreach (var character in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
filePath = filePath.Replace(character, '-');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filePath = String.Empty;
|
||||
}
|
||||
|
||||
//Break up the file in name and extension before applying the UrlReplaceCharacters
|
||||
var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.'));
|
||||
var ext = filePath.Substring(filePath.LastIndexOf('.'));
|
||||
|
||||
//Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters'
|
||||
XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
|
||||
foreach (XmlNode n in replaceChars.SelectNodes("char"))
|
||||
{
|
||||
if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
|
||||
fileNamePart = fileNamePart.Replace(n.Attributes.GetNamedItem("org").Value, XmlHelper.GetNodeValue(n));
|
||||
}
|
||||
|
||||
filePath = string.Concat(fileNamePart, ext);
|
||||
|
||||
// Adapted from: http://stackoverflow.com/a/4827510/5018
|
||||
// Combined both Reserved Characters and Character Data
|
||||
// from http://en.wikipedia.org/wiki/Percent-encoding
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
const string reservedCharacters = "!*'();:@&=+$,/?%#[]-~{}\"<>\\^`| ";
|
||||
|
||||
foreach (var character in filePath)
|
||||
{
|
||||
if (reservedCharacters.IndexOf(character) == -1)
|
||||
stringBuilder.Append(character);
|
||||
else
|
||||
stringBuilder.Append("-");
|
||||
}
|
||||
|
||||
// Remove repeating dashes
|
||||
// From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character
|
||||
var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-");
|
||||
|
||||
return reducedString;
|
||||
// use string extensions
|
||||
return filePath.ToSafeFileName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal class ResizedImage
|
||||
{
|
||||
public ResizedImage()
|
||||
{
|
||||
}
|
||||
|
||||
public ResizedImage(int width, int height, string fileName)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
public string FileName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
public class UmbracoMediaFile
|
||||
{
|
||||
private readonly MediaFileSystem _fs;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public UmbracoMediaFile()
|
||||
{
|
||||
_fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
|
||||
}
|
||||
|
||||
public UmbracoMediaFile(string path)
|
||||
{
|
||||
_fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
|
||||
|
||||
Path = path;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
|
||||
//MB: Do we really need all these overloads? looking through the code, only one of them is actually used
|
||||
|
||||
public static UmbracoMediaFile Save(HttpPostedFile file, string path)
|
||||
{
|
||||
return Save(file.InputStream, path);
|
||||
}
|
||||
|
||||
public static UmbracoMediaFile Save(HttpPostedFileBase file, string path)
|
||||
{
|
||||
return Save(file.InputStream, path);
|
||||
}
|
||||
|
||||
public static UmbracoMediaFile Save(Stream inputStream, string path)
|
||||
{
|
||||
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
|
||||
fs.AddFile(path, inputStream);
|
||||
|
||||
return new UmbracoMediaFile(path);
|
||||
}
|
||||
|
||||
public static UmbracoMediaFile Save(byte[] file, string relativePath)
|
||||
{
|
||||
return Save(new MemoryStream(file), relativePath);
|
||||
}
|
||||
|
||||
public static UmbracoMediaFile Save(HttpPostedFile file)
|
||||
{
|
||||
var tempDir = System.IO.Path.Combine("uploads", Guid.NewGuid().ToString());
|
||||
return Save(file, tempDir);
|
||||
}
|
||||
|
||||
//filebase overload...
|
||||
public static UmbracoMediaFile Save(HttpPostedFileBase file)
|
||||
{
|
||||
var tempDir = System.IO.Path.Combine("uploads", Guid.NewGuid().ToString());
|
||||
return Save(file, tempDir);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private long? _length;
|
||||
private Size? _size;
|
||||
|
||||
/// <summary>
|
||||
/// Initialized values that don't require opening the file.
|
||||
/// </summary>
|
||||
private void Initialize()
|
||||
{
|
||||
Filename = _fs.GetFileName(Path);
|
||||
Extension = _fs.GetExtension(Path) != null
|
||||
? _fs.GetExtension(Path).Substring(1).ToLowerInvariant()
|
||||
: "";
|
||||
Url = _fs.GetUrl(Path);
|
||||
}
|
||||
|
||||
public string Filename { get; private set; }
|
||||
|
||||
public string Extension { get; private set; }
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public string Url { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the length of the file in bytes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We are lazy loading this, don't go opening the file on ctor like we were doing.
|
||||
/// </remarks>
|
||||
public long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_length == null)
|
||||
{
|
||||
_length = _fs.GetSize(Path);
|
||||
}
|
||||
return _length.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsResizing
|
||||
{
|
||||
get
|
||||
{
|
||||
return ("," + UmbracoSettings.ImageFileTypes + ",").Contains(string.Format(",{0},", Extension));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFriendlyName()
|
||||
{
|
||||
return Filename.SplitPascalCasing().ToFirstUpperInvariant();
|
||||
}
|
||||
|
||||
public Size GetDimensions()
|
||||
{
|
||||
if (_size == null)
|
||||
{
|
||||
EnsureFileSupportsResizing();
|
||||
|
||||
var fs = _fs.OpenFile(Path);
|
||||
var image = Image.FromStream(fs);
|
||||
var fileWidth = image.Width;
|
||||
var fileHeight = image.Height;
|
||||
fs.Close();
|
||||
image.Dispose();
|
||||
|
||||
_size = new Size(fileWidth, fileHeight);
|
||||
}
|
||||
return _size.Value;
|
||||
}
|
||||
|
||||
public string Resize(int width, int height)
|
||||
{
|
||||
EnsureFileSupportsResizing();
|
||||
|
||||
var fileNameThumb = DoResize(width, height, 0, string.Empty);
|
||||
|
||||
return _fs.GetUrl(fileNameThumb);
|
||||
}
|
||||
|
||||
public string Resize(int maxWidthHeight, string fileNameAddition)
|
||||
{
|
||||
EnsureFileSupportsResizing();
|
||||
|
||||
var fileNameThumb = DoResize(GetDimensions().Width, GetDimensions().Height, maxWidthHeight, fileNameAddition);
|
||||
|
||||
return _fs.GetUrl(fileNameThumb);
|
||||
}
|
||||
|
||||
private string DoResize(int width, int height, int maxWidthHeight, string fileNameAddition)
|
||||
{
|
||||
using (var fs = _fs.OpenFile(Path))
|
||||
{
|
||||
using (var image = Image.FromStream(fs))
|
||||
{
|
||||
var fileNameThumb = string.IsNullOrWhiteSpace(fileNameAddition)
|
||||
? string.Format("{0}_UMBRACOSYSTHUMBNAIL.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)))
|
||||
: string.Format("{0}_{1}.jpg", Path.Substring(0, Path.LastIndexOf(".", StringComparison.Ordinal)), fileNameAddition);
|
||||
|
||||
var thumbnail = GenerateThumbnail(image, maxWidthHeight, width, height, fileNameThumb, maxWidthHeight == 0);
|
||||
|
||||
return thumbnail.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureFileSupportsResizing()
|
||||
{
|
||||
if (SupportsResizing == false)
|
||||
throw new InvalidOperationException(string.Format("The file {0} is not an image, so can't get dimensions", Filename));
|
||||
}
|
||||
|
||||
private ResizedImage GenerateThumbnail(Image image, int maxWidthHeight, int fileWidth, int fileHeight, string thumbnailFileName, bool useFixedDimensions)
|
||||
{
|
||||
// Generate thumbnail
|
||||
float f = 1;
|
||||
if (useFixedDimensions == false)
|
||||
{
|
||||
var fx = (float)image.Size.Width / (float)maxWidthHeight;
|
||||
var fy = (float)image.Size.Height / (float)maxWidthHeight;
|
||||
|
||||
// must fit in thumbnail size
|
||||
f = Math.Max(fx, fy);
|
||||
}
|
||||
|
||||
var widthTh = (int)Math.Round((float)fileWidth / f);
|
||||
var heightTh = (int)Math.Round((float)fileHeight / f);
|
||||
|
||||
// fixes for empty width or height
|
||||
if (widthTh == 0)
|
||||
widthTh = 1;
|
||||
if (heightTh == 0)
|
||||
heightTh = 1;
|
||||
|
||||
// Create new image with best quality settings
|
||||
using (var bp = new Bitmap(widthTh, heightTh))
|
||||
{
|
||||
using (var g = Graphics.FromImage(bp))
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
g.CompositingQuality = CompositingQuality.HighQuality;
|
||||
|
||||
// Copy the old image to the new and resized
|
||||
var rect = new Rectangle(0, 0, widthTh, heightTh);
|
||||
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
|
||||
|
||||
// Copy metadata
|
||||
var imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
|
||||
var codec = Extension.ToLower() == "png" || Extension.ToLower() == "gif"
|
||||
? imageEncoders.Single(t => t.MimeType.Equals("image/png"))
|
||||
: imageEncoders.Single(t => t.MimeType.Equals("image/jpeg"));
|
||||
|
||||
// Set compresion ratio to 90%
|
||||
var ep = new EncoderParameters();
|
||||
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
|
||||
|
||||
// Save the new image using the dimensions of the image
|
||||
var newFileName = thumbnailFileName.Replace("UMBRACOSYSTHUMBNAIL", string.Format("{0}x{1}", widthTh, heightTh));
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
bp.Save(ms, codec, ep);
|
||||
ms.Seek(0, 0);
|
||||
|
||||
_fs.AddFile(newFileName, ms);
|
||||
}
|
||||
|
||||
return new ResizedImage(widthTh, heightTh, newFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all <see cref="IMacroPropertyType"/> objects
|
||||
/// </summary>
|
||||
internal sealed class MacroPropertyTypeResolver : ManyObjectsResolverBase<MacroPropertyTypeResolver, IMacroPropertyType>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="macroPropertyTypes"></param>
|
||||
internal MacroPropertyTypeResolver(IEnumerable<Type> macroPropertyTypes)
|
||||
: base(macroPropertyTypes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroPropertyType"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IMacroPropertyType> MacroPropertyTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -3,10 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using Umbraco.Core.Macros;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
namespace Umbraco.Core.Macros
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IMacroGuiRendering objects
|
||||
@@ -24,9 +25,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <param name="macroEditors"></param>
|
||||
internal MacroFieldEditorsResolver(Func<IEnumerable<Type>> macroEditors)
|
||||
: base(macroEditors, ObjectLifetimeScope.Transient)
|
||||
{
|
||||
|
||||
}
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroGuiRendering"/> implementations.
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentAll : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentAll"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentPicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentPicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentRandom : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentRandom"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentStubs : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentStubs"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentTree : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentTree"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "content"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentType : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentType"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "contentTypeSingle"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class ContentTypeMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "contentTypeMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "contentTypeMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class MediaCurrent : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "mediaCurrent"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "media"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class Number : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "number"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "numeric"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Int32; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class PropertyTypePicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "propertyTypePicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "propertyTypePicker"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class PropertyTypePickerMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "propertyTypePickerMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "propertyTypePickerMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TabPicker : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "tabPicker"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "tabPicker"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TabPickerMultiple : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "tabPickerMultiple"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "tabPickerMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class Text : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "text"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "text"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class TextMultiLine : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "textMultiLine"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "textMultiple"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.String; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Macros.PropertyTypes
|
||||
{
|
||||
internal class YesNoBool : IMacroPropertyType
|
||||
{
|
||||
public string Alias
|
||||
{
|
||||
get { return "bool"; }
|
||||
}
|
||||
|
||||
public string RenderingAssembly
|
||||
{
|
||||
get { return "umbraco.macroRenderings"; }
|
||||
}
|
||||
|
||||
public string RenderingType
|
||||
{
|
||||
get { return "yesNo"; }
|
||||
}
|
||||
|
||||
public MacroPropertyTypeBaseTypes BaseType
|
||||
{
|
||||
get { return MacroPropertyTypeBaseTypes.Boolean; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -20,7 +22,7 @@ namespace Umbraco.Core.Models
|
||||
private DateTime? _expireDate;
|
||||
private int _writer;
|
||||
private string _nodeName;//NOTE Once localization is introduced this will be the non-localized Node Name.
|
||||
|
||||
private bool _permissionsChanged;
|
||||
/// <summary>
|
||||
/// Constructor for creating a Content object
|
||||
/// </summary>
|
||||
@@ -80,6 +82,7 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo ExpireDateSelector = ExpressionHelper.GetPropertyInfo<Content, DateTime?>(x => x.ExpireDate);
|
||||
private static readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo<Content, int>(x => x.WriterId);
|
||||
private static readonly PropertyInfo NodeNameSelector = ExpressionHelper.GetPropertyInfo<Content, string>(x => x.NodeName);
|
||||
private static readonly PropertyInfo PermissionsChangedSelector = ExpressionHelper.GetPropertyInfo<Content, bool>(x => x.PermissionsChanged);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the template used by the Content.
|
||||
@@ -101,8 +104,11 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
set
|
||||
{
|
||||
_template = value;
|
||||
OnPropertyChanged(TemplateSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_template = value;
|
||||
return _template;
|
||||
}, _template, TemplateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,15 +139,21 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Boolean indicating whether this Content is Published or not
|
||||
/// </summary>
|
||||
/// <remarks>Setting Published to true/false should be private or internal</remarks>
|
||||
/// <remarks>
|
||||
/// Setting Published to true/false should be private or internal and should ONLY be used for wiring up the value
|
||||
/// from the db or modifying it based on changing the published state.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public bool Published
|
||||
{
|
||||
get { return _published; }
|
||||
internal set
|
||||
{
|
||||
_published = value;
|
||||
OnPropertyChanged(PublishedSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_published = value;
|
||||
return _published;
|
||||
}, _published, PublishedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +169,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _language; }
|
||||
set
|
||||
{
|
||||
_language = value;
|
||||
OnPropertyChanged(LanguageSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_language = value;
|
||||
return _language;
|
||||
}, _language, LanguageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,8 +186,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _releaseDate; }
|
||||
set
|
||||
{
|
||||
_releaseDate = value;
|
||||
OnPropertyChanged(ReleaseDateSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_releaseDate = value;
|
||||
return _releaseDate;
|
||||
}, _releaseDate, ReleaseDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,8 +203,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _expireDate; }
|
||||
set
|
||||
{
|
||||
_expireDate = value;
|
||||
OnPropertyChanged(ExpireDateSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_expireDate = value;
|
||||
return _expireDate;
|
||||
}, _expireDate, ExpireDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,8 +220,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _writer; }
|
||||
set
|
||||
{
|
||||
_writer = value;
|
||||
OnPropertyChanged(WriterSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_writer = value;
|
||||
return _writer;
|
||||
}, _writer, WriterSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,8 +239,27 @@ namespace Umbraco.Core.Models
|
||||
get { return _nodeName; }
|
||||
set
|
||||
{
|
||||
_nodeName = value;
|
||||
OnPropertyChanged(NodeNameSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_nodeName = value;
|
||||
return _nodeName;
|
||||
}, _nodeName, NodeNameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to track if permissions have been changed during the saving process for this entity
|
||||
/// </summary>
|
||||
internal bool PermissionsChanged
|
||||
{
|
||||
get { return _permissionsChanged; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_permissionsChanged = value;
|
||||
return _permissionsChanged;
|
||||
}, _permissionsChanged, PermissionsChangedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,11 +375,25 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public override bool IsDirty()
|
||||
{
|
||||
bool dirtyEntity = base.IsDirty();
|
||||
return IsEntityDirty() || IsAnyUserPropertyDirty();
|
||||
}
|
||||
|
||||
bool dirtyProperties = Properties.Any(x => x.IsDirty());
|
||||
/// <summary>
|
||||
/// Returns true if only the entity properties are direty
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal bool IsEntityDirty()
|
||||
{
|
||||
return base.IsDirty();
|
||||
}
|
||||
|
||||
return dirtyEntity || dirtyProperties;
|
||||
/// <summary>
|
||||
/// Returns true if any of the properties are dirty
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal bool IsAnyUserPropertyDirty()
|
||||
{
|
||||
return Properties.Any(x => x.IsDirty());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -13,6 +14,7 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Represents an abstract class for base Content properties and methods
|
||||
/// </summary>
|
||||
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
|
||||
public abstract class ContentBase : Entity, IContentBase
|
||||
{
|
||||
protected IContentTypeComposition ContentTypeBase;
|
||||
@@ -25,6 +27,7 @@ namespace Umbraco.Core.Models
|
||||
private bool _trashed;
|
||||
private int _contentTypeId;
|
||||
private PropertyCollection _properties;
|
||||
private readonly List<Property> _lastInvalidProperties = new List<Property>();
|
||||
|
||||
/// <summary>
|
||||
/// Protected constructor for ContentBase (Base for Content and Media)
|
||||
@@ -118,8 +121,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +138,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,8 +155,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,8 +172,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,8 +189,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(CreatorIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,8 +208,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
internal set
|
||||
{
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +231,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _contentTypeId; }
|
||||
protected set
|
||||
{
|
||||
_contentTypeId = value;
|
||||
OnPropertyChanged(DefaultContentTypeIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeId = value;
|
||||
return _contentTypeId;
|
||||
}, _contentTypeId, DefaultContentTypeIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +293,10 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
if (Properties[propertyTypeAlias].Value is TPassType)
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
|
||||
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -398,9 +425,34 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>True if content is valid otherwise false</returns>
|
||||
public virtual bool IsValid()
|
||||
{
|
||||
return Properties.Any(property => !property.IsValid()) == false;
|
||||
_lastInvalidProperties.Clear();
|
||||
_lastInvalidProperties.AddRange(Properties.Where(property => property.IsValid() == false));
|
||||
return _lastInvalidProperties.Any() == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of the result of the last validation process, this collection contains all invalid properties.
|
||||
/// </summary>
|
||||
internal IEnumerable<Property> LastInvalidProperties
|
||||
{
|
||||
get { return _lastInvalidProperties; }
|
||||
}
|
||||
|
||||
public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20);
|
||||
|
||||
/// <summary>
|
||||
/// We will override this method to ensure that when we reset the dirty properties that we
|
||||
/// also reset the dirty changes made to the content's Properties (user defined)
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties"></param>
|
||||
internal override void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
base.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
|
||||
foreach (var prop in Properties)
|
||||
{
|
||||
prop.ResetDirtyProperties(rememberPreviouslyChangedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
@@ -11,14 +12,246 @@ using System.Xml.Linq;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Media;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class ContentExtensions
|
||||
{
|
||||
#region IContent
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// A new version needs to be created when:
|
||||
/// * The publish status is changed
|
||||
/// * The language is changed
|
||||
/// * The item is already published and is being published again and any property value is changed (to enable a rollback)
|
||||
/// </remarks>
|
||||
internal static bool ShouldCreateNewVersion(this IContent entity)
|
||||
{
|
||||
var publishedState = ((Content)entity).PublishedState;
|
||||
return ShouldCreateNewVersion(entity, publishedState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="publishedState"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// A new version needs to be created when:
|
||||
/// * The publish status is changed
|
||||
/// * The language is changed
|
||||
/// * The item is already published and is being published again and any property value is changed (to enable a rollback)
|
||||
/// </remarks>
|
||||
internal static bool ShouldCreateNewVersion(this IContent entity, PublishedState publishedState)
|
||||
{
|
||||
var dirtyEntity = (ICanBeDirty)entity;
|
||||
|
||||
//check if the published state has changed or the language
|
||||
var contentChanged =
|
||||
(dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished)
|
||||
|| dirtyEntity.IsPropertyDirty("Language");
|
||||
|
||||
//return true if published or language has changed
|
||||
if (contentChanged)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if any user prop has changed
|
||||
var propertyValueChanged = ((Content) entity).IsAnyUserPropertyDirty();
|
||||
//check if any content prop has changed
|
||||
var contentDataChanged = ((Content) entity).IsEntityDirty();
|
||||
|
||||
//return true if the item is published and a property has changed or if any content property has changed
|
||||
return (propertyValueChanged && publishedState == PublishedState.Published) || contentDataChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the published db flag should be set to true for the current entity version and all other db
|
||||
/// versions should have their flag set to false.
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is determined by:
|
||||
/// * If a new version is being created and the entity is published
|
||||
/// * If the published state has changed and the entity is published OR the entity has been un-published.
|
||||
/// </remarks>
|
||||
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity)
|
||||
{
|
||||
var publishedState = ((Content)entity).PublishedState;
|
||||
return entity.ShouldClearPublishedFlagForPreviousVersions(publishedState, entity.ShouldCreateNewVersion(publishedState));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the published db flag should be set to true for the current entity version and all other db
|
||||
/// versions should have their flag set to false.
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="publishedState"></param>
|
||||
/// <param name="isCreatingNewVersion"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is determined by:
|
||||
/// * If a new version is being created and the entity is published
|
||||
/// * If the published state has changed and the entity is published OR the entity has been un-published.
|
||||
/// </remarks>
|
||||
internal static bool ShouldClearPublishedFlagForPreviousVersions(this IContent entity, PublishedState publishedState, bool isCreatingNewVersion)
|
||||
{
|
||||
if (isCreatingNewVersion && entity.Published)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//If Published state has changed then previous versions should have their publish state reset.
|
||||
//If state has been changed to unpublished the previous versions publish state should also be reset.
|
||||
if (((ICanBeDirty)entity).IsPropertyDirty("Published") && (entity.Published || publishedState == PublishedState.Unpublished))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents ancestors, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Ancestors(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetAncestors(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents children.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Children(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetChildren(content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents descendants, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Descendants(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetDescendants(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current content.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An <see cref="IContent"/> object</returns>
|
||||
public static IContent Parent(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetById(content.ParentId);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IMedia
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias ancestors, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Ancestors(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetAncestors(media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias children.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Children(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetChildren(media.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias descendants, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Descendants(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetDescendants(media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current media.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An <see cref="IMedia"/> object</returns>
|
||||
public static IMedia Parent(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetById(media.ParentId);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the IContentBase has children
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is a bit of a hack because we need to type check!
|
||||
/// </remarks>
|
||||
internal static bool HasChildren(IContentBase content, ServiceContext services)
|
||||
{
|
||||
if (content is IContent)
|
||||
{
|
||||
return services.ContentService.HasChildren(content.Id);
|
||||
}
|
||||
if (content is IMedia)
|
||||
{
|
||||
return services.MediaService.HasChildren(content.Id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the children for the content base item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is a bit of a hack because we need to type check!
|
||||
/// </remarks>
|
||||
internal static IEnumerable<IContentBase> Children(IContentBase content, ServiceContext services)
|
||||
{
|
||||
if (content is IContent)
|
||||
{
|
||||
return services.ContentService.GetChildren(content.Id);
|
||||
}
|
||||
if (content is IMedia)
|
||||
{
|
||||
return services.MediaService.GetChildren(content.Id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set property values by alias with an annonymous object
|
||||
/// </summary>
|
||||
@@ -165,7 +398,7 @@ namespace Umbraco.Core.Models
|
||||
var thumbUrl = Resize(fs, fileName, extension, 100, "thumb");
|
||||
|
||||
//Look up Prevalues for this upload datatype - if it is an upload datatype
|
||||
var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
|
||||
var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField);
|
||||
if (property.PropertyType.DataTypeId == uploadFieldId)
|
||||
{
|
||||
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
|
||||
@@ -337,8 +570,16 @@ namespace Umbraco.Core.Models
|
||||
return new Tuple<int, int, string>(widthTh, heightTh, newFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
|
||||
/// </summary>
|
||||
public static IProfile GetCreatorProfile(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.UserService.GetProfileById(media.CreatorId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this content/media item.
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this content item.
|
||||
/// </summary>
|
||||
public static IProfile GetCreatorProfile(this IContentBase content)
|
||||
{
|
||||
@@ -366,6 +607,16 @@ namespace Umbraco.Core.Models
|
||||
return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
|
||||
/// </summary>
|
||||
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
internal static XElement ToDeepXml(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
@@ -373,21 +624,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IContent content)
|
||||
{
|
||||
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
||||
|
||||
var x = content.ToXml(nodeName);
|
||||
x.Add(new XAttribute("nodeType", content.ContentType.Id));
|
||||
x.Add(new XAttribute("creatorName", content.GetCreatorProfile().Name));
|
||||
x.Add(new XAttribute("writerName", content.GetWriterProfile().Name));
|
||||
x.Add(new XAttribute("writerID", content.WriterId));
|
||||
x.Add(new XAttribute("template", content.Template == null ? "0" : content.Template.Id.ToString()));
|
||||
if (UmbracoSettings.UseLegacyXmlSchema)
|
||||
{
|
||||
x.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias));
|
||||
}
|
||||
|
||||
return x;
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -397,59 +634,12 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IMedia media)
|
||||
{
|
||||
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : media.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
||||
|
||||
var x = media.ToXml(nodeName);
|
||||
x.Add(new XAttribute("nodeType", media.ContentType.Id));
|
||||
x.Add(new XAttribute("writerName", media.GetCreatorProfile().Name));
|
||||
x.Add(new XAttribute("writerID", media.CreatorId));
|
||||
x.Add(new XAttribute("version", media.Version));
|
||||
x.Add(new XAttribute("template", 0));
|
||||
if (UmbracoSettings.UseLegacyXmlSchema)
|
||||
{
|
||||
x.Add(new XAttribute("nodeTypeAlias", media.ContentType.Alias));
|
||||
}
|
||||
|
||||
return x;
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IContentBase"/> object
|
||||
/// </summary>
|
||||
/// <param name="contentBase"><see cref="IContent"/> to generate xml for</param>
|
||||
/// <param name="nodeName"></param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
private static XElement ToXml(this IContentBase contentBase, string nodeName)
|
||||
internal static XElement ToDeepXml(this IMedia media)
|
||||
{
|
||||
var niceUrl = contentBase.Name.FormatUrl().ToLower();
|
||||
|
||||
var xml = new XElement(nodeName,
|
||||
new XAttribute("id", contentBase.Id),
|
||||
new XAttribute("parentID", contentBase.Level > 1 ? contentBase.ParentId : -1),
|
||||
new XAttribute("level", contentBase.Level),
|
||||
new XAttribute("creatorID", contentBase.CreatorId),
|
||||
new XAttribute("sortOrder", contentBase.SortOrder),
|
||||
new XAttribute("createDate", contentBase.CreateDate.ToString("s")),
|
||||
new XAttribute("updateDate", contentBase.UpdateDate.ToString("s")),
|
||||
new XAttribute("nodeName", contentBase.Name),
|
||||
new XAttribute("urlName", niceUrl),//Format Url ?
|
||||
new XAttribute("path", contentBase.Path),
|
||||
new XAttribute("isDoc", ""));
|
||||
|
||||
foreach (var property in contentBase.Properties)
|
||||
{
|
||||
if (property == null) continue;
|
||||
|
||||
xml.Add(property.ToXml());
|
||||
|
||||
//Check for umbracoUrlName convention
|
||||
if (property.Alias == "umbracoUrlName" && property.Value != null &&
|
||||
property.Value.ToString().Trim() != string.Empty)
|
||||
xml.SetAttributeValue("urlName", property.Value.ToString().FormatUrl().ToLower());
|
||||
}
|
||||
|
||||
return xml;
|
||||
return ApplicationContext.Current.Services.PackagingService.Export(media, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -15,12 +15,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
private int _defaultTemplate;
|
||||
private IEnumerable<ITemplate> _allowedTemplates;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor for creating a ContentType with the parent's id.
|
||||
/// </summary>
|
||||
/// <remarks>You usually only want to use this for creating ContentTypes at the root.</remarks>
|
||||
/// <param name="parentId"></param>
|
||||
public ContentType(int parentId) : base(parentId)
|
||||
{
|
||||
_allowedTemplates = new List<ITemplate>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constuctor for creating a ContentType with the parent as an inherited type.
|
||||
/// </summary>
|
||||
/// <remarks>Use this to ensure inheritance from parent.</remarks>
|
||||
/// <param name="parent"></param>
|
||||
public ContentType(IContentType parent) : base(parent)
|
||||
{
|
||||
_allowedTemplates = new List<ITemplate>();
|
||||
@@ -47,8 +57,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _defaultTemplate; }
|
||||
set
|
||||
{
|
||||
_defaultTemplate = value;
|
||||
OnPropertyChanged(DefaultTemplateSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_defaultTemplate = value;
|
||||
return _defaultTemplate;
|
||||
}, _defaultTemplate, DefaultTemplateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +74,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedTemplates; }
|
||||
set
|
||||
{
|
||||
_allowedTemplates = value;
|
||||
OnPropertyChanged(AllowedTemplatesSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedTemplates = value;
|
||||
return _allowedTemplates;
|
||||
}, _allowedTemplates, AllowedTemplatesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,14 +161,56 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.ResetDirtyProperties();
|
||||
|
||||
//loop through each property group to reset the property types
|
||||
var propertiesReset = new List<int>();
|
||||
|
||||
foreach (var propertyGroup in PropertyGroups)
|
||||
{
|
||||
propertyGroup.ResetDirtyProperties();
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
{
|
||||
propertyType.ResetDirtyProperties();
|
||||
propertiesReset.Add(propertyType.Id);
|
||||
}
|
||||
}
|
||||
//then loop through our property type collection since some might not exist on a property group
|
||||
//but don't re-reset ones we've already done.
|
||||
foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false))
|
||||
{
|
||||
propertyType.ResetDirtyProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a clone of the current entity
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IContentType Clone(string alias)
|
||||
{
|
||||
var clone = (ContentType)this.MemberwiseClone();
|
||||
clone.Alias = alias;
|
||||
clone.Key = Guid.Empty;
|
||||
var propertyGroups = this.PropertyGroups.Select(x => x.Clone()).ToList();
|
||||
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
|
||||
clone.PropertyTypes = this.PropertyTypeCollection.Select(x => x.Clone()).ToList();
|
||||
clone.ResetIdentity();
|
||||
clone.ResetDirtyProperties(false);
|
||||
|
||||
foreach (var propertyGroup in clone.PropertyGroups)
|
||||
{
|
||||
propertyGroup.ResetIdentity();
|
||||
foreach (var propertyType in propertyGroup.PropertyTypes)
|
||||
{
|
||||
propertyType.ResetIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var propertyType in clone.PropertyTypes.Where(x => x.HasIdentity))
|
||||
{
|
||||
propertyType.ResetIdentity();
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Umbraco.Core.Models
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _sortOrder;
|
||||
private string _icon;
|
||||
private string _thumbnail;
|
||||
private string _icon = "folder.png";
|
||||
private string _thumbnail = "folder.png";
|
||||
private int _creatorId;
|
||||
private bool _allowedAsRoot;
|
||||
private bool _isContainer;
|
||||
@@ -31,6 +31,8 @@ namespace Umbraco.Core.Models
|
||||
private PropertyGroupCollection _propertyGroups;
|
||||
private PropertyTypeCollection _propertyTypes;
|
||||
private IEnumerable<ContentTypeSort> _allowedContentTypes;
|
||||
private bool _hasPropertyTypeBeenRemoved;
|
||||
|
||||
|
||||
protected ContentTypeBase(int parentId)
|
||||
{
|
||||
@@ -68,6 +70,8 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<ContentTypeSort>>(x => x.AllowedContentTypes);
|
||||
private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, PropertyGroupCollection>(x => x.PropertyGroups);
|
||||
private static readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<PropertyType>>(x => x.PropertyTypes);
|
||||
private static readonly PropertyInfo HasPropertyTypeBeenRemovedSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.HasPropertyTypeBeenRemoved);
|
||||
|
||||
|
||||
protected void PropertyGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
@@ -111,8 +115,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +132,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +149,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,8 +166,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
_alias = value.ToSafeAlias();
|
||||
OnPropertyChanged(AliasSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value.ToSafeAlias();
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +183,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _description; }
|
||||
set
|
||||
{
|
||||
_description = value;
|
||||
OnPropertyChanged(DescriptionSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_description = value;
|
||||
return _description;
|
||||
}, _description, DescriptionSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +200,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,8 +217,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _icon; }
|
||||
set
|
||||
{
|
||||
_icon = value;
|
||||
OnPropertyChanged(IconSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_icon = value;
|
||||
return _icon;
|
||||
}, _icon, IconSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,8 +234,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _thumbnail; }
|
||||
set
|
||||
{
|
||||
_thumbnail = value;
|
||||
OnPropertyChanged(ThumbnailSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_thumbnail = value;
|
||||
return _thumbnail;
|
||||
}, _thumbnail, ThumbnailSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +251,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(CreatorIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,8 +268,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedAsRoot; }
|
||||
set
|
||||
{
|
||||
_allowedAsRoot = value;
|
||||
OnPropertyChanged(AllowedAsRootSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedAsRoot = value;
|
||||
return _allowedAsRoot;
|
||||
}, _allowedAsRoot, AllowedAsRootSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,8 +288,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _isContainer; }
|
||||
set
|
||||
{
|
||||
_isContainer = value;
|
||||
OnPropertyChanged(IsContainerSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isContainer = value;
|
||||
return _isContainer;
|
||||
}, _isContainer, IsContainerSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,8 +306,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
set
|
||||
{
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,8 +323,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedContentTypes; }
|
||||
set
|
||||
{
|
||||
_allowedContentTypes = value;
|
||||
OnPropertyChanged(AllowedContentTypesSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedContentTypes = value;
|
||||
return _allowedContentTypes;
|
||||
}, _allowedContentTypes, AllowedContentTypesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +365,24 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A boolean flag indicating if a property type has been removed from this instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is currently (specifically) used in order to know that we need to refresh the content cache which
|
||||
/// needs to occur when a property has been removed from a content type
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
internal bool HasPropertyTypeBeenRemoved
|
||||
{
|
||||
get { return _hasPropertyTypeBeenRemoved; }
|
||||
private set
|
||||
{
|
||||
_hasPropertyTypeBeenRemoved = value;
|
||||
OnPropertyChanged(HasPropertyTypeBeenRemovedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a PropertyType with a given alias already exists
|
||||
/// </summary>
|
||||
@@ -396,6 +457,15 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="propertyTypeAlias">Alias of the <see cref="PropertyType"/> to remove</param>
|
||||
public void RemovePropertyType(string propertyTypeAlias)
|
||||
{
|
||||
|
||||
//check if the property exist in one of our collections
|
||||
if (PropertyGroups.Any(group => group.PropertyTypes.Any(pt => pt.Alias == propertyTypeAlias))
|
||||
|| _propertyTypes.Any(x => x.Alias == propertyTypeAlias))
|
||||
{
|
||||
//set the flag that a property has been removed
|
||||
HasPropertyTypeBeenRemoved = true;
|
||||
}
|
||||
|
||||
foreach (var propertyGroup in PropertyGroups)
|
||||
{
|
||||
propertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
|
||||
@@ -403,10 +473,19 @@ namespace Umbraco.Core.Models
|
||||
|
||||
if (_propertyTypes.Any(x => x.Alias == propertyTypeAlias))
|
||||
{
|
||||
_propertyTypes.RemoveItem(propertyTypeAlias);
|
||||
_propertyTypes.RemoveItem(propertyTypeAlias);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a PropertyGroup from the current ContentType
|
||||
/// </summary>
|
||||
/// <param name="propertyGroupName">Name of the <see cref="PropertyGroup"/> to remove</param>
|
||||
public void RemovePropertyGroup(string propertyGroupName)
|
||||
{
|
||||
PropertyGroups.RemoveItem(propertyGroupName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ParentId from the lazy integer id
|
||||
/// </summary>
|
||||
@@ -415,5 +494,14 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_parentId = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyTypes that are not part of a PropertyGroup
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal PropertyTypeCollection PropertyTypeCollection
|
||||
{
|
||||
get { return _propertyTypes; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,10 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
}
|
||||
|
||||
protected ContentTypeCompositionBase(IContentTypeBase parent) : base(parent)
|
||||
protected ContentTypeCompositionBase(IContentTypeComposition parent)
|
||||
: base(parent)
|
||||
{
|
||||
AddContentType(parent);
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo ContentTypeCompositionSelector =
|
||||
@@ -73,7 +75,7 @@ namespace Umbraco.Core.Models
|
||||
if (contentType.ContentTypeComposition.Any(x => x.CompositionAliases().Any(ContentTypeCompositionExists)))
|
||||
return false;
|
||||
|
||||
if (!ContentTypeCompositionExists(contentType.Alias))
|
||||
if (ContentTypeCompositionExists(contentType.Alias) == false)
|
||||
{
|
||||
_contentTypeComposition.Add(contentType);
|
||||
OnPropertyChanged(ContentTypeCompositionSelector);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal static class ContentTypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all descendant content types
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<IContentTypeBase> Descendants(this IContentTypeBase contentType)
|
||||
{
|
||||
var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
|
||||
var descendants = contentTypeService.GetContentTypeChildren(contentType.Id)
|
||||
.FlattenList(type => contentTypeService.GetContentTypeChildren(type.Id));
|
||||
return descendants;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all descendant and self content types
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<IContentTypeBase> DescendantsAndSelf(this IContentTypeBase contentType)
|
||||
{
|
||||
var descendantsAndSelf = new[] { contentType }.Concat(contentType.Descendants());
|
||||
return descendantsAndSelf;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Returns the descendant content type Ids for the given content type
|
||||
///// </summary>
|
||||
///// <param name="contentType"></param>
|
||||
///// <returns></returns>
|
||||
//public static IEnumerable<int> DescendantIds(this IContentTypeBase contentType)
|
||||
//{
|
||||
// return ((ContentTypeService) ApplicationContext.Current.Services.ContentTypeService)
|
||||
// .GetDescendantContentTypeIds(contentType.Id);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -52,8 +53,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
_parentId = value;
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +70,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +87,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,8 +104,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,8 +121,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +138,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(UserIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, UserIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +155,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
internal set
|
||||
{
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,9 +171,12 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _controlId; }
|
||||
private set
|
||||
{
|
||||
_controlId = value;
|
||||
OnPropertyChanged(ControlIdSelector);
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_controlId = value;
|
||||
return _controlId;
|
||||
}, _controlId, ControlIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,9 +188,12 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _databaseType; }
|
||||
set
|
||||
{
|
||||
_databaseType = value;
|
||||
OnPropertyChanged(DatabaseTypeSelector);
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_databaseType = value;
|
||||
return _databaseType;
|
||||
}, _databaseType, DatabaseTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -41,8 +42,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
_parentId = value;
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +59,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _itemKey; }
|
||||
set
|
||||
{
|
||||
_itemKey = value;
|
||||
OnPropertyChanged(ItemKeySelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_itemKey = value;
|
||||
return _itemKey;
|
||||
}, _itemKey, ItemKeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +76,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _translations; }
|
||||
set
|
||||
{
|
||||
_translations = value;
|
||||
OnPropertyChanged(TranslationsSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_translations = value;
|
||||
return _translations;
|
||||
}, _translations, TranslationsSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -40,8 +41,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _language; }
|
||||
set
|
||||
{
|
||||
_language = value;
|
||||
OnPropertyChanged(LanguageSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_language = value;
|
||||
return _language;
|
||||
}, _language, LanguageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +58,11 @@ namespace Umbraco.Core.Models
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
OnPropertyChanged(ValueSelector);
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_value = value;
|
||||
return _value;
|
||||
}, _value, ValueSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -12,12 +10,24 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public abstract class Entity : IEntity, ICanBeDirty
|
||||
[DebuggerDisplay("Id: {Id}")]
|
||||
public abstract class Entity : TracksChangesEntityBase, IEntity, IRememberBeingDirty, ICanBeDirty
|
||||
{
|
||||
private bool _hasIdentity;
|
||||
private int? _hash;
|
||||
private int _id;
|
||||
private Guid _key;
|
||||
private DateTime _createDate;
|
||||
private DateTime _updateDate;
|
||||
private bool _wasCancelled;
|
||||
|
||||
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<Entity, int>(x => x.Id);
|
||||
private static readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo<Entity, Guid>(x => x.Key);
|
||||
private static readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.CreateDate);
|
||||
private static readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.UpdateDate);
|
||||
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.HasIdentity);
|
||||
private static readonly PropertyInfo WasCancelledSelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.WasCancelled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id
|
||||
@@ -31,8 +41,12 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
}
|
||||
set
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,46 +65,67 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
|
||||
return _key;
|
||||
}
|
||||
set { _key = value; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_key = value;
|
||||
return _key;
|
||||
}, _key, KeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Created Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime CreateDate { get; set; }
|
||||
public DateTime CreateDate
|
||||
{
|
||||
get { return _createDate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_createDate = value;
|
||||
return _createDate;
|
||||
}, _createDate, CreateDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modified Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// /// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
internal bool WasCancelled
|
||||
{
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
get { return _wasCancelled; }
|
||||
set
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_wasCancelled = value;
|
||||
return _wasCancelled;
|
||||
}, _wasCancelled, WasCancelledSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modified Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime UpdateDate
|
||||
{
|
||||
get { return _updateDate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_updateDate = value;
|
||||
return _updateDate;
|
||||
}, _updateDate, UpdateDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,42 +152,6 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity has an identity, eg. Id.
|
||||
/// </summary>
|
||||
@@ -164,7 +163,11 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
}
|
||||
protected set
|
||||
{
|
||||
_hasIdentity = value;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that defines if the object is tracking property changes and that is is also
|
||||
/// remembering what property changes had been made after the changes were committed.
|
||||
/// </summary>
|
||||
public interface IRememberBeingDirty : ICanBeDirty
|
||||
{
|
||||
bool WasDirty();
|
||||
bool WasPropertyDirty(string propertyName);
|
||||
void ForgetPreviouslyDirtyProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for use to implement IRememberBeingDirty/ICanBeDirty
|
||||
/// </summary>
|
||||
public abstract class TracksChangesEntityBase : IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
|
||||
/// </summary>
|
||||
private IDictionary<string, bool> _lastPropertyChangedInfo = null;
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
{
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entity had been changed and the changes were committed
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool WasDirty()
|
||||
{
|
||||
return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity was changed and the changes were committed
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property was changed, otherwise False. Returns false if the entity had not been previously changed.</returns>
|
||||
public virtual bool WasPropertyDirty(string propertyName)
|
||||
{
|
||||
return WasDirty() && _lastPropertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the remembered dirty properties from before the last commit
|
||||
/// </summary>
|
||||
public void ForgetPreviouslyDirtyProperties()
|
||||
{
|
||||
_lastPropertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
ResetDirtyProperties(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties">
|
||||
/// true if we are to remember the last changes made after resetting
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
internal virtual void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
if (rememberPreviouslyChangedProperties)
|
||||
{
|
||||
//copy the changed properties to the last changed properties
|
||||
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
|
||||
}
|
||||
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by inheritors to set the value of properties, this will detect if the property value actually changed and if it did
|
||||
/// it will ensure that the property has a dirty flag set.
|
||||
/// </summary>
|
||||
/// <param name="setValue"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="propertySelector"></param>
|
||||
/// <returns>returns true if the value changed</returns>
|
||||
/// <remarks>
|
||||
/// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
|
||||
/// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
|
||||
/// to the same value, so it's really not dirty.
|
||||
/// </remarks>
|
||||
internal bool SetPropertyValueAndDetectChanges<T>(Func<T, T> setValue, T value, PropertyInfo propertySelector)
|
||||
{
|
||||
var initVal = value;
|
||||
var newVal = setValue(value);
|
||||
if (!Equals(initVal, newVal))
|
||||
{
|
||||
OnPropertyChanged(propertySelector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -12,11 +13,17 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public abstract class File : Entity, IFile
|
||||
{
|
||||
private string _path;
|
||||
private string _content = string.Empty; //initialize to empty string, not null
|
||||
|
||||
protected File(string path)
|
||||
{
|
||||
Path = path;
|
||||
_path = path;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Content);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the File including extension
|
||||
/// </summary>
|
||||
@@ -48,13 +55,35 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Path to the File from the root of the site
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public virtual string Path { get; set; }
|
||||
public virtual string Path
|
||||
{
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content of a File
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public virtual string Content { get; set; }
|
||||
public virtual string Content
|
||||
{
|
||||
get { return _content; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_content = value;
|
||||
return _content;
|
||||
}, _content, ContentSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether the file could be validated
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a Content object
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public interface IContent : IContentBase
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user