Compare commits
958 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a460404252 | |||
| d0287608b6 | |||
| 1532376710 | |||
| d3122db7b2 | |||
| b46b8933ab | |||
| 62f3e6db75 | |||
| 217f3ca0b4 | |||
| 3eba7538a4 | |||
| fa6f5db97f | |||
| ebea829d80 | |||
| e319c49891 | |||
| efd0a9f5f1 | |||
| 94888d5fd4 | |||
| ac8b064f47 | |||
| 3c133bff49 | |||
| 20bb3f7f2a | |||
| cc1f78a83d | |||
| ff02fd8aca | |||
| 063a2fadaa | |||
| 266b7328ef | |||
| 893b8e4cef | |||
| 1772de2531 | |||
| 75dc3a71b7 | |||
| 0be82dedb6 | |||
| 8a76674568 | |||
| 40800c97b2 | |||
| 6926f6dcc7 | |||
| a63cd1b06f | |||
| 9cf370cfb6 | |||
| ccaefcf69a | |||
| 15eb5ca4b8 | |||
| 224528f1de | |||
| ad2b61db80 | |||
| 344c8f6b5c | |||
| 4bc70ed401 | |||
| b95a6f57bf | |||
| 87e37e82fd | |||
| 8519cc796f | |||
| 827bd1f899 | |||
| ed0436d21e | |||
| 242746fd17 | |||
| f23fd0ee5e | |||
| 1087b3cb4e | |||
| f60c9b00ab | |||
| 6fe9b616aa | |||
| 655550e23a | |||
| 4bada2b954 | |||
| a87a1b7d3b | |||
| 4fae3b0a85 | |||
| 052bdfc17e | |||
| 476b8902bb | |||
| 6f0b92138f | |||
| cd271fc485 | |||
| 0bf65303ca | |||
| c4800fc6da | |||
| d51c2e05d3 | |||
| ce096afed7 | |||
| 06e7e7ff7b | |||
| bbbda080bf | |||
| 574f3faf06 | |||
| b56c86457c | |||
| 7212386e98 | |||
| b73a175386 | |||
| c9e6fec4bf | |||
| fcd37d0c7b | |||
| b40cd4e73f | |||
| 1b6e21d7a6 | |||
| 7ee1972599 | |||
| 24479b479d | |||
| 90a1a78b1e | |||
| 4a50075784 | |||
| 606bea72e1 | |||
| 4eb603430d | |||
| 76b1e0babe | |||
| f2248e604d | |||
| f56791e6c4 | |||
| 750d904a16 | |||
| 691a03f176 | |||
| 48fb171d7a | |||
| 8fd0512a3c | |||
| 5b16d508b5 | |||
| 05e313ad28 | |||
| b9fa7d2c9c | |||
| 8ce508cab0 | |||
| dffbec1c44 | |||
| ad0eccb4cd | |||
| 44d35257e8 | |||
| cf8a5e1eed | |||
| 6b0894c66a | |||
| a7058a5a13 | |||
| 1403af5be3 | |||
| 20b4d7d621 | |||
| 7331ed3e80 | |||
| 79dd109e37 | |||
| a305326973 | |||
| 3dca040a0b | |||
| 8327f1c371 | |||
| 73c833780c | |||
| f2cc1db1a8 | |||
| 34c2d1bdd1 | |||
| 29e95769b5 | |||
| e3c44f9c0f | |||
| 40d2042228 | |||
| ab494e4ede | |||
| 1cd02d55fb | |||
| f183f72bf4 | |||
| 8b6c710b09 | |||
| 04b589420e | |||
| e38e46ecdb | |||
| ace428669b | |||
| b37110cc82 | |||
| cde2fc3842 | |||
| ffcd442989 | |||
| 76dd27e7f7 | |||
| a0822259e7 | |||
| 9b8283d0fc | |||
| 04a7674bdd | |||
| 2d4cfc58ec | |||
| 0dc4797a4c | |||
| b668db242d | |||
| bbfe6fa50b | |||
| a15108e65b | |||
| aa1083bdac | |||
| b3c720b1c3 | |||
| 657245dcbd | |||
| 5af2555f59 | |||
| 49882dc151 | |||
| 19438d3021 | |||
| d5c481c2f4 | |||
| 8763e4efde | |||
| ecb8c1389c | |||
| d05f5eeb1d | |||
| 4362417495 | |||
| a9bbe11169 | |||
| 45e60cb52a | |||
| 211068ce50 | |||
| 051f7fb28c | |||
| 79666a3046 | |||
| 78abff6a52 | |||
| 1daa8e4a0f | |||
| dc76489221 | |||
| 7c503c4438 | |||
| a34d920847 | |||
| 2e8625c25f | |||
| 280972a66c | |||
| 200c758ff4 | |||
| 9f3477a279 | |||
| 046b931624 | |||
| 70549136ba | |||
| 6c0c750000 | |||
| 2f3c05651e | |||
| fa9a7bbb3c | |||
| 830612f555 | |||
| af8292c1de | |||
| 38cf3413df | |||
| 800868e27e | |||
| 7dd8b5026d | |||
| 6da20812ce | |||
| 887b015def | |||
| 505a74ad1d | |||
| 83cac9ac05 | |||
| a818ff2000 | |||
| 0ce85e0a7f | |||
| 86edff4447 | |||
| ebd6bf6007 | |||
| 1f78bd8471 | |||
| f83ffc3ac3 | |||
| 392f9a1b9c | |||
| 9f8541ef2a | |||
| cca9284b6a | |||
| 3e87066506 | |||
| 9cf6bac1a5 | |||
| b738bea9ca | |||
| 9c67b1b829 | |||
| 955fc67438 | |||
| 91b6be3186 | |||
| 17065e613f | |||
| cec19bd866 | |||
| 5594d7d054 | |||
| 2b58426b2d | |||
| 6a4bbf0fe5 | |||
| 8e68391a57 | |||
| 93edcab52e | |||
| ccd0b381b6 | |||
| d259f73665 | |||
| 0f6273cdb8 | |||
| 4e067ceabd | |||
| 58dbe10388 | |||
| d423113b00 | |||
| 26452f891f | |||
| 2f26729c84 | |||
| b6a3c8866a | |||
| d610968932 | |||
| 26b77483ee | |||
| d14e3f1e22 | |||
| b3cda72e93 | |||
| 3602405ec0 | |||
| d59536deea | |||
| 6400371ff9 | |||
| c1aad6d574 | |||
| cc1ec61b85 | |||
| c710f977b2 | |||
| 5425b0dd82 | |||
| 4247b37551 | |||
| 82980a148b | |||
| c13aac1bc3 | |||
| da87848cee | |||
| 25052a76ca | |||
| a13ff95777 | |||
| cdda041a90 | |||
| 6924253423 | |||
| 69213014d1 | |||
| aa126ba458 | |||
| c9563378ea | |||
| ba22fb1cef | |||
| 29cd317aff | |||
| 0bf95d865a | |||
| ae43ec99d9 | |||
| 7f186e21e0 | |||
| bca2853ade | |||
| 97d54f2ac8 | |||
| 8142d4b1e6 | |||
| 35d4e27588 | |||
| ec15d0a784 | |||
| c93a5c137f | |||
| 752cd4a8ef | |||
| 5d198e2b98 | |||
| 1d14e65315 | |||
| 67a8848aed | |||
| 30bd273580 | |||
| cbc75befb5 | |||
| a9f5e572dd | |||
| 8038b38802 | |||
| 79024eb004 | |||
| 0c3db64585 | |||
| 3dc8d84229 | |||
| 87f01ea2e9 | |||
| 0b9bb8cb78 | |||
| 009669360d | |||
| a342945b61 | |||
| 1fce49fac7 | |||
| a50583fb97 | |||
| d18ff7d956 | |||
| 3ec62cf95a | |||
| ab157bbb75 | |||
| f61ffec352 | |||
| 88f0e31622 | |||
| 38eecef26b | |||
| 99408dfcf3 | |||
| 0bf0dfe10d | |||
| e3b00bcaf5 | |||
| 6caba976ec | |||
| 1d6a9ac25a | |||
| 03e501dedd | |||
| 18209292a4 | |||
| 007f26e582 | |||
| 04b43dc097 | |||
| becc5bfbf2 | |||
| 230fa05eb7 | |||
| 96834a47b0 | |||
| e212e6b12a | |||
| 404adf970d | |||
| 7d5d9ea449 | |||
| 74e09e562b | |||
| 60c3a4d3e1 | |||
| f3f0b11393 | |||
| f2b6b4e230 | |||
| 6a3c510157 | |||
| 4555c38d3b | |||
| 24696800e5 | |||
| 818b186f8a | |||
| 4910af33ff | |||
| 0626e52f3c | |||
| f034640ca3 | |||
| 1829b362fc | |||
| 34acb02cbb | |||
| 4877836b12 | |||
| 07ed2b0231 | |||
| 9c743ab965 | |||
| 78bddb22be | |||
| decc23aaf2 | |||
| 2395a3802a | |||
| 7ec445b06e | |||
| 21f29fe492 | |||
| 5b5e47c3ae | |||
| b6413975c3 | |||
| d151b51c67 | |||
| 827f5b42a6 | |||
| ef17914960 | |||
| 72a857158c | |||
| 87090d8ae7 | |||
| 8af31ae0f7 | |||
| feecea2806 | |||
| 07da861126 | |||
| c97d23c533 | |||
| 4d99bae893 | |||
| 2a6440c134 | |||
| 4dbba60439 | |||
| 29cf52b677 | |||
| fd86559a5b | |||
| d70dd7ac69 | |||
| 43c7b978c3 | |||
| dfff18f81b | |||
| a4a870e1ec | |||
| 03303cd71b | |||
| c2cf7075c2 | |||
| bfe1ad6dbc | |||
| 6212acfc81 | |||
| 847f57686e | |||
| 44fd0faa23 | |||
| df6c8b3be9 | |||
| a192c21c6a | |||
| f3312ce58d | |||
| 603ecb0052 | |||
| 4a74d9857c | |||
| 7256e9e139 | |||
| f09d76b0ea | |||
| 0f859c6f32 | |||
| 389d751e92 | |||
| 5ce3978472 | |||
| d5f36a8d9e | |||
| 08f539f738 | |||
| 6e8030a0db | |||
| b96b075b55 | |||
| f8e9d8bdbc | |||
| bf20b541ae | |||
| 3945335f39 | |||
| 2c534c184d | |||
| a8ef1f3f43 | |||
| 86da39886d | |||
| a7f39918bf | |||
| 69c57493e7 | |||
| 5fe1948097 | |||
| d9b51a21fa | |||
| 9cb9ab552b | |||
| 7a873ef1d7 | |||
| 292cd0dbd5 | |||
| f86784c22d | |||
| 2dd5c1e4a3 | |||
| 29d9c0ffe1 | |||
| d7ee9f986b | |||
| 1bcbe8bebf | |||
| db117db3c5 | |||
| 4a16f33dcc | |||
| 0d67b00d5d | |||
| 7d2f1aa279 | |||
| bfa32856bc | |||
| 06e1a9a98a | |||
| d9bb0cdeb8 | |||
| 4d2bd6e507 | |||
| a297fb1e38 | |||
| a4585f7eaa | |||
| 182faf2696 | |||
| d967a1fa14 | |||
| 22db488d21 | |||
| 1be13ba1fc | |||
| d6d8a045e6 | |||
| 1d0995bb8e | |||
| 3345c9dc39 | |||
| fecb62a396 | |||
| ad697686c0 | |||
| cdada41505 | |||
| 08718c01e4 | |||
| b152f2b6ba | |||
| 04fbe8f5ef | |||
| e68348f627 | |||
| 9591ee2603 | |||
| 5814ef0d25 | |||
| d607330557 | |||
| ad03eb6286 | |||
| cc60cbbbab | |||
| d619120fc4 | |||
| 2c4e7a1cea | |||
| a33a3d2afb | |||
| 03832b45e1 | |||
| 028e34b6c4 | |||
| ad53faf25c | |||
| 0c51bfea6f | |||
| 6fa3f70bc2 | |||
| db41c907aa | |||
| 2a97194253 | |||
| a7048bc45d | |||
| eb5b677250 | |||
| 897b2b5302 | |||
| 5805ac4574 | |||
| 07e028fe5c | |||
| 08dde123b1 | |||
| 82cff5af70 | |||
| 8754bd88a5 | |||
| 6a915551ab | |||
| ed02e38e1d | |||
| 8d7cd2ccd5 | |||
| c0586a906c | |||
| 181d16fe22 | |||
| 3ee27ee6ba | |||
| 6775da70a8 | |||
| f7382cd8c3 | |||
| 7339b0b08d | |||
| 1acd18510a | |||
| fb26cc9375 | |||
| d47a05a9a5 | |||
| 17b2afefad | |||
| 4744cb0e1d | |||
| 7c6aa8d826 | |||
| b3f7b7d200 | |||
| 1ab567f6e3 | |||
| f0d584503f | |||
| 042486c511 | |||
| ded2c63312 | |||
| bf79463070 | |||
| f98373cc34 | |||
| 25114854b3 | |||
| 4ca17924a1 | |||
| 9a010227d7 | |||
| e1a625ad35 | |||
| eace9f914d | |||
| d3b52886f5 | |||
| 71b0d53c5e | |||
| 11c680f97a | |||
| 223268c2fa | |||
| 53e3158dfe | |||
| 31a10069a5 | |||
| 4c14936353 | |||
| 2bb207d005 | |||
| d429305836 | |||
| 49c803425c | |||
| cf75bb31e9 | |||
| fc52df0677 | |||
| 6065553c13 | |||
| 346380e131 | |||
| affbd83b48 | |||
| 381d182726 | |||
| 2048661b0c | |||
| 6a0329f756 | |||
| 35c7e0a69c | |||
| decb9a5814 | |||
| 61e79d9344 | |||
| 36a733af8d | |||
| a8464c9719 | |||
| e145f767f3 | |||
| 56532c4e72 | |||
| fa37042b32 | |||
| 0e7f04b04e | |||
| cbcae4037c | |||
| 72f7ff0589 | |||
| 2c83741171 | |||
| 78dd437928 | |||
| f5b5622a89 | |||
| bb75d2b01a | |||
| 2cf87a4da1 | |||
| 9fad46bd0e | |||
| dcc73856a9 | |||
| 4b842b20ce | |||
| 49b56f19d8 | |||
| 25e1213d1b | |||
| 92fc97eeb3 | |||
| 48e063904d | |||
| 99679d0688 | |||
| d3b47e9470 | |||
| 1570a65381 | |||
| d4949327ef | |||
| c9bd17a100 | |||
| 0a022f9a39 | |||
| 565bb72d99 | |||
| e5382002b4 | |||
| 3628b24d12 | |||
| cd425599ce | |||
| e7345a2c4f | |||
| 032e0ca13a | |||
| 3ade95a3d7 | |||
| fddf4fbacc | |||
| 926acd7bba | |||
| 8975653d4c | |||
| 689de3dbcc | |||
| ab5bb94b12 | |||
| 6203ef8e51 | |||
| e83cf5a787 | |||
| d09a5674e9 | |||
| d0a599bbae | |||
| 30c12d3927 | |||
| 860473f33c | |||
| e1cfef7bf1 | |||
| b4fd2154fe | |||
| f37891fdb6 | |||
| aad8fbab09 | |||
| 7785f0c75f | |||
| a71dc5d7d0 | |||
| 655214ab30 | |||
| fb5a9666ed | |||
| 60ca369cd3 | |||
| b89d5a2bf4 | |||
| 53ae58e1a1 | |||
| 792097fb6a | |||
| 970cfb1166 | |||
| 01cd443441 | |||
| 488fc63b67 | |||
| 6285e57c49 | |||
| 243e13ab59 | |||
| 5e98c2183a | |||
| 9f3148fec7 | |||
| c9357429fd | |||
| 41265e07d4 | |||
| 2e4440c3f8 | |||
| 3141347214 | |||
| 943ac3c77e | |||
| 83b47311ba | |||
| 16fd1cce61 | |||
| f14807de06 | |||
| ed2853564e | |||
| 26170f4613 | |||
| 68268c0199 | |||
| 5966d2c2d3 | |||
| 26929c08d3 | |||
| 044bf638a8 | |||
| 58f6269f36 | |||
| 3a68883ae9 | |||
| 211ed48361 | |||
| c515ffec9c | |||
| 4e09039d2c | |||
| 1e1e4e4eca | |||
| c8265d95b0 | |||
| 2e384abab6 | |||
| 736a4fb77e | |||
| 38dafee05d | |||
| fa0bfb775a | |||
| 445a1a1c8d | |||
| 1e1fd6f24d | |||
| a678f9df38 | |||
| f85bfdf186 | |||
| cae70cdbdb | |||
| ebae8c8315 | |||
| 6af66b1106 | |||
| f355d2c87f | |||
| f4fbfaa7cb | |||
| 21f50d5a08 | |||
| 1b539ba1ec | |||
| 3e0e7e1208 | |||
| b8fdd2d85f | |||
| c95b78a8ce | |||
| 3ae345b3d7 | |||
| d1d3498b62 | |||
| f878daeb8b | |||
| 9ba98a0abe | |||
| 1cecaa7926 | |||
| 2744d07d71 | |||
| 5ed8050791 | |||
| c3b261e321 | |||
| 9ffce01e0c | |||
| 8905191413 | |||
| b4b22940df | |||
| e1cf0fda27 | |||
| f41d00ed8a | |||
| d866e8be91 | |||
| be4c8197eb | |||
| fcb5fd27e2 | |||
| 9c9b226589 | |||
| a562e3905a | |||
| 607e12b4f2 | |||
| 7f66783976 | |||
| 2abcccb371 | |||
| 9bc32632af | |||
| 52e3f58c72 | |||
| b5c1ed1227 | |||
| 4d058d4824 | |||
| cb4fba5a33 | |||
| 4a84d94e91 | |||
| 0b57c6825a | |||
| 529db4861d | |||
| 9de34d4e84 | |||
| d7ad5d6560 | |||
| aeea7c6af0 | |||
| b1bfd4cb0c | |||
| 2eb111a300 | |||
| 76e487cd7e | |||
| 60fc4f4b1a | |||
| da5fc42f61 | |||
| 1151e9cc8f | |||
| dfde415198 | |||
| e2b83a8298 | |||
| 5cfafc6110 | |||
| 1810c13b55 | |||
| a0aa150418 | |||
| 5c8d438c08 | |||
| 17bd2cc94c | |||
| cbfd5a1019 | |||
| 04fcbad8c5 | |||
| 5df72bb4a4 | |||
| 41acd466ce | |||
| 43c1115eeb | |||
| db75a4425c | |||
| 0f9d3ef173 | |||
| 05d6dd487c | |||
| d460914f65 | |||
| 6bf4702608 | |||
| f014856424 | |||
| c432fa1674 | |||
| f778e47283 | |||
| 4886ed6d36 | |||
| 74ec445a66 | |||
| 6cab59c340 | |||
| 2e2ebe5ec7 | |||
| 68e2061666 | |||
| 7b171c7340 | |||
| 5bea1a4d31 | |||
| 9e7c840b18 | |||
| ac4d114214 | |||
| d5501950e2 | |||
| 42c80841c8 | |||
| 0b5c6ff319 | |||
| 05b6401817 | |||
| 59cc585271 | |||
| f0133fe5f4 | |||
| b8bb2b4ab6 | |||
| 72c20a5297 | |||
| 5846b0f1b3 | |||
| 39cc09dfc3 | |||
| 678f2cb6ee | |||
| 13991e5288 | |||
| 5c0ad7376a | |||
| af1daea191 | |||
| 9772578ee2 | |||
| 16ac4e3dbe | |||
| 2ab37d6205 | |||
| e070b9b511 | |||
| e232d5532a | |||
| 74dc587452 | |||
| 87a44f4704 | |||
| c2b7a11c77 | |||
| 7a4482b8a4 | |||
| defa7754a4 | |||
| 1bf152a551 | |||
| 99c8761b75 | |||
| 0c2f453750 | |||
| d7aec74403 | |||
| 760d44d194 | |||
| f2d3ee98a6 | |||
| 705f04937f | |||
| 5862c872c6 | |||
| b7066c0333 | |||
| e4178da65c | |||
| c7abf20bbe | |||
| b3a2586ecf | |||
| 45e9e0f565 | |||
| 352523640d | |||
| 05824223a9 | |||
| f616ab60ef | |||
| 363bc4eb86 | |||
| 2b191d8c37 | |||
| 7d7ed6a0ee | |||
| 83020b993c | |||
| 985ce3ec53 | |||
| 33fe6a46a4 | |||
| cd8a344156 | |||
| 6ae804853f | |||
| b6d859fa92 | |||
| 1a0d776394 | |||
| 1ba1628ed6 | |||
| 027b4e1568 | |||
| df6afaf090 | |||
| c1e24b0461 | |||
| 36b9219842 | |||
| 8e76eaad19 | |||
| fad925644f | |||
| a84f77d6ba | |||
| 0c994bd934 | |||
| 18889e230a | |||
| e557b7bb44 | |||
| 3ae9190e78 | |||
| e231f3f023 | |||
| 2502e1359c | |||
| 20f00edd15 | |||
| 2f3425dff6 | |||
| 272600ff80 | |||
| 1745ebc832 | |||
| 5188585864 | |||
| 1e98ee1de0 | |||
| 5011388f39 | |||
| 5e07dc8b51 | |||
| 894c36ea32 | |||
| 031df528b6 | |||
| 9d3b88b379 | |||
| 5eebe4e50d | |||
| 2916d24b20 | |||
| 3352332f3f | |||
| 2621569200 | |||
| 93eed12505 | |||
| 125f9ee838 | |||
| 8df8eb6c95 | |||
| bf7516112f | |||
| 5a26af476e | |||
| 2287bf06f5 | |||
| 89812ec81c | |||
| 06fef43180 | |||
| 01e671f4d1 | |||
| d47d2533ac | |||
| 27a74816da | |||
| 47baa1077e | |||
| f0f7b94362 | |||
| 747c6698b6 | |||
| 8f91e10faa | |||
| 6cd8af85da | |||
| 34d67c835e | |||
| 7f17a38d35 | |||
| 07ae20eeed | |||
| 4cc3c2ac17 | |||
| 66e074b43d | |||
| eb44ca4213 | |||
| dfbbc14b33 | |||
| 34bf601a56 | |||
| 969a91a1e3 | |||
| fbe8e27568 | |||
| 4ee705a79c | |||
| 8623a53200 | |||
| 4e5b04113d | |||
| 3cc22aab82 | |||
| be2b9055b9 | |||
| 92cd6e9af8 | |||
| 58ace4941e | |||
| 37527034ab | |||
| 88e1108f11 | |||
| 3408ed48ba | |||
| b8c67f8068 | |||
| 79026b73a8 | |||
| 6a6c1c1172 | |||
| 18bd1cc3b1 | |||
| 74c0733c1e | |||
| f55f734fda | |||
| d477db2cfb | |||
| 6fe07ab815 | |||
| 1a1142893f | |||
| 7bda34c66b | |||
| 2af5015668 | |||
| 5801355cbc | |||
| d6b28d43c8 | |||
| 6d7e6f5e36 | |||
| 469590fde5 | |||
| 00dbaf90bc | |||
| 705250b93d | |||
| 0d64be15de | |||
| f6597c7cb9 | |||
| a8778dc23e | |||
| d62dfd88d2 | |||
| d081f272b0 | |||
| 1b2abab6dd | |||
| 10ab20d8e2 | |||
| 48207b6814 | |||
| 1a08e7b6f6 | |||
| b9523a0ba0 | |||
| 084ec2a63d | |||
| b9e0514783 | |||
| 3e05742568 | |||
| 660b998eb7 | |||
| b084cde854 | |||
| 8ca368e7e3 | |||
| a0fd7c5b44 | |||
| 7eb64927cc | |||
| 9074534c93 | |||
| 12d9cfbcaa | |||
| f3a6080fce | |||
| f16b0747a4 | |||
| 964481d023 | |||
| d143cae25a | |||
| d11e2bcf48 | |||
| 3c33e40b61 | |||
| eaf2c769be | |||
| ce4a1dcc19 | |||
| 2230a38cd6 | |||
| ef6051b95e | |||
| af1d279226 | |||
| d5ce28df67 | |||
| 693b3f8677 | |||
| a322312740 | |||
| 2edde7fe33 | |||
| 08a12b6dbb | |||
| 876bb3af42 | |||
| 7f9f5281e5 | |||
| 3eb049036e | |||
| 093f1efb21 | |||
| 7d1778bbd2 | |||
| 5ebf6eeca1 | |||
| 6fb4600334 | |||
| b6b36e1b5a | |||
| c51be6b697 | |||
| 063fc1a7ba | |||
| 07a5909d73 | |||
| ec3972361d | |||
| fccd59e2e3 | |||
| eb16ab407b | |||
| e6ba035911 | |||
| 8e1ed353bb | |||
| a4990dd294 | |||
| b4f5c46ab0 | |||
| 6fa7d08860 | |||
| 3044b21eb6 | |||
| d7e8dd590c | |||
| b66802446d | |||
| d7c2f0cc47 | |||
| 27574abf46 | |||
| e6a8dd60af | |||
| 1cbd70639c | |||
| 217bacc663 | |||
| 83954e711d | |||
| 149df445d6 | |||
| 38b95e7be9 | |||
| db4767e22b | |||
| 66b6a3b5e2 | |||
| 7374ff30ef | |||
| 06cf8fb963 | |||
| 6a7d779024 | |||
| 5ae45084dc | |||
| 38b418b7d6 | |||
| fa5f9764ae | |||
| fd99a8c02d | |||
| 0269cd8213 | |||
| d29b3e5f9e | |||
| cb844c4238 | |||
| 679b6b85ad | |||
| 258d7032bb | |||
| 6d7defc87c | |||
| b548b2192c | |||
| f3e4f109a3 | |||
| 8413a63f7d | |||
| 76beb27135 | |||
| 12c9c72984 | |||
| cf9e886076 | |||
| 3008e36a3e | |||
| b64a882696 | |||
| 8be8c44596 | |||
| b48fd706b7 | |||
| d9afe1abd7 | |||
| 70c39d1618 | |||
| ffc966d72f | |||
| 1e0f9166cc | |||
| c2618ca791 | |||
| 4b4afc7322 | |||
| 8340fedd64 | |||
| b194cf21dc | |||
| 29773c9729 | |||
| fd21828080 | |||
| a458cff25e | |||
| e93c7c9c46 | |||
| 00e4700abb | |||
| 096fb74bf1 | |||
| 64fa45e262 | |||
| 57c91e427d | |||
| 2bf93dc034 | |||
| 746f93c290 | |||
| 38330bfd65 | |||
| 2fdcbd1ac3 | |||
| 8d52e6b4e3 | |||
| e8d1f1e5f0 | |||
| 7ba37bd91a | |||
| 9067b484ce | |||
| c3df0ebdc2 | |||
| abed0f2122 | |||
| 12c4098773 | |||
| bb5a7d9ede | |||
| 1c9cd3463b | |||
| 6bc2da5191 | |||
| 042b590606 | |||
| 0b05568c9f | |||
| 2021fc614e | |||
| c0d321c1bf | |||
| 20ced8a806 | |||
| b448a9214c | |||
| 4a2912880f | |||
| ca1b0a1a6f | |||
| 86848edc84 | |||
| f93aaa65c4 | |||
| cd03b575df | |||
| 667009727a | |||
| 6a9e4bfc90 | |||
| 15493df62d | |||
| 82051a6a6a | |||
| 5bf30b0060 | |||
| baea9b6de5 | |||
| fa0483b361 | |||
| b58e261db9 | |||
| d8d1542e52 | |||
| 56ab22d02c | |||
| 6c15854448 | |||
| d91787589b | |||
| 3d8bded89e | |||
| 5f9bff0f71 | |||
| 301e4c5acb | |||
| 82757801b9 | |||
| 9a8b4ff4ed | |||
| 572e758bf2 | |||
| 64f8970215 | |||
| a3436d4cba | |||
| 07ee09f49a | |||
| 25b5caeed1 | |||
| 313f4ca785 | |||
| ed06f04077 | |||
| 7aa8ccc47d | |||
| 04b55e97de | |||
| 76e9ca2acf | |||
| 77dea8a234 | |||
| 01c0e050ad | |||
| 339d510fda | |||
| 6e5f8db8bb | |||
| 145f50402e | |||
| 1d517de67b | |||
| c7ec97ce98 | |||
| b916bcfccc | |||
| 580d60b941 | |||
| 68857cea8c | |||
| bc1ee8524e | |||
| 8d3275bee4 | |||
| 7ce7ec4c94 | |||
| 17a9cb9608 | |||
| f6df40db46 | |||
| 6fb3a2a185 | |||
| d28a7ca30f | |||
| 6a361945ea | |||
| 55821e04c1 | |||
| b161295d0b | |||
| 4d0e254491 | |||
| 3252078501 | |||
| 21e0af98eb | |||
| 7f959169b7 | |||
| e4ed594d82 | |||
| a12832488d | |||
| a62788c61e | |||
| 3208d538a7 | |||
| 2a1791a4b1 | |||
| 63c35580c7 | |||
| c765c3679f | |||
| eb1af59219 | |||
| 3ba5f81b7b | |||
| 07b9821e24 | |||
| 15771f4452 | |||
| 3dcab1a782 | |||
| 46b77928f7 | |||
| 68abd9c71b | |||
| d51ecb6ea8 | |||
| 7d2eb7a7b9 | |||
| 4f5b44bd3b | |||
| 2b840e0cfb | |||
| 8cbb2a8802 | |||
| c67e13e04b | |||
| afe60d614b | |||
| 161395d709 | |||
| 5ffe5cf541 | |||
| 8069e235fd | |||
| 45161a6402 | |||
| a4565e88ed | |||
| f6c9baab3e | |||
| da2c5d6fc3 | |||
| 408f3df28e | |||
| 2ee436eaa1 | |||
| 02ea9f0769 | |||
| 99dd7d3877 | |||
| 4d8bcc0c6b | |||
| 538cdfa883 | |||
| 70b5d24f72 | |||
| 3db95a85de | |||
| 95a7596cb4 |
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
assets/*
|
||||
cache/*
|
||||
vendor
|
||||
composer.phar
|
||||
db/poche.sqlite
|
||||
inc/poche/config.inc.php
|
||||
inc/3rdparty/htmlpurifier/HTMLPurifier/DefinitionCache/Serializer/
|
||||
.vagrant
|
||||
30
CONTRIBUTING.md
Normal file
@ -0,0 +1,30 @@
|
||||
# How to contribute
|
||||
|
||||
## You found a bug
|
||||
Please [open a new issue](https://github.com/wallabag/wallabag/issues/new).
|
||||
|
||||
To fix the bug quickly, we need some infos:
|
||||
* your wallabag version (on top of the ./index.php file, and also on config page)
|
||||
* your webserver installation :
|
||||
* type of hosting (shared or dedicaced)
|
||||
* in case of a dedicaced server, the server and OS used
|
||||
* the php version used, eventually `phpinfo()`
|
||||
* which storage system you choose at install (SQLite, MySQL/MariaDB or PostgreSQL)
|
||||
* any problem on the `wallabag_compatibility_test.php` page
|
||||
* any particular details which could be related
|
||||
|
||||
|
||||
If relevant :
|
||||
* the link you want to save and which causes problem
|
||||
* the file you want to import into wallabag, or just an extract
|
||||
|
||||
If you have the skills :
|
||||
* enable DEBUG mode and look the output at cache/log.txt
|
||||
* look for errors into php and server logs
|
||||
|
||||
Note : If you have large portions of text, use [Github's Gist service](https://gist.github.com/) or other pastebin-like.
|
||||
|
||||
## You want to fix a bug or to add a feature
|
||||
Please fork wallabag and work with **the dev branch** only. **Do not work on master branch**.
|
||||
|
||||
[Don't forget to read our guidelines](https://github.com/wallabag/wallabag/blob/dev/GUIDELINES.md).
|
||||
14
COPYING
@ -1,14 +0,0 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
||||
19
COPYING.md
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013-2014 Nicolas Lœuillet
|
||||
|
||||
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.
|
||||
16
CREDITS
@ -1,16 +0,0 @@
|
||||
poche is based on :
|
||||
* ReadItYourself http://www.memiks.fr/readityourself/
|
||||
* PHP Readability http://www.keyvan.net/2010/08/php-readability/
|
||||
* Encoding https://github.com/neitanod/forceutf8
|
||||
* logo by Brightmix http://www.iconfinder.com/icondetails/43256/128/jeans_monotone_pocket_icon
|
||||
* icons http://icomoon.io
|
||||
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
|
||||
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
|
||||
|
||||
poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
|
||||
|
||||
Contributors :
|
||||
Nicolas Lœuillet aka nico_somb
|
||||
Tom.C. aka tmos
|
||||
PeaceCopathe
|
||||
Gregoire_M
|
||||
17
CREDITS.md
Normal file
@ -0,0 +1,17 @@
|
||||
wallabag is based on :
|
||||
* PHP Readability https://bitbucket.org/fivefilters/php-readability
|
||||
* Full Text RSS http://code.fivefilters.org/full-text-rss/src
|
||||
* logo by Maylis Agniel https://github.com/wallabag/logo
|
||||
* icons http://icomoon.io
|
||||
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
|
||||
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
|
||||
* Twig http://twig.sensiolabs.org
|
||||
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
|
||||
* Pagination https://github.com/daveismyname/pagination
|
||||
* PHPePub https://github.com/Grandt/PHPePub/
|
||||
|
||||
wallabag is mainly developed by Nicolas Lœuillet under the MIT License
|
||||
|
||||
Thank you so much to @tcitworld and @mariroz.
|
||||
|
||||
Contributors : https://github.com/wallabag/wallabag/graphs/contributors
|
||||
53
GUIDELINES.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Guidelines for wallabag
|
||||
|
||||
If you want to contribute to wallabag, you have some rules to respect. These rules were defined by [PHP Framework Interop Group](http://www.php-fig.org).
|
||||
|
||||
## Basic Coding Standard (PSR-1)
|
||||
|
||||
This section of the standard comprises what should be considered the standard coding elements that are required to ensure a high level of technical interoperability between shared PHP code.
|
||||
|
||||
* Files MUST use only `<?php` and `<?=` tags.
|
||||
|
||||
* Files MUST use only UTF-8 without BOM for PHP code.
|
||||
|
||||
* Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both.
|
||||
|
||||
* Namespaces and classes MUST follow [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
|
||||
|
||||
* Class names MUST be declared in `StudlyCaps`.
|
||||
|
||||
* Class constants MUST be declared in all upper case with underscore separators.
|
||||
|
||||
* Method names MUST be declared in `camelCase`.
|
||||
|
||||
You can read details on [PHP FIG website](http://www.php-fig.org/psr/psr-1/).
|
||||
|
||||
## Coding Style Guide (PSR-2)
|
||||
|
||||
This guide extends and expands on PSR-1, the basic coding standard.
|
||||
|
||||
The intent of this guide is to reduce cognitive friction when scanning code from different authors. It does so by enumerating a shared set of rules and expectations about how to format PHP code.
|
||||
|
||||
The style rules herein are derived from commonalities among the various member projects. When various authors collaborate across multiple projects, it helps to have one set of guidelines to be used among all those projects. Thus, the benefit of this guide is not in the rules themselves, but in the sharing of those rules.
|
||||
|
||||
* Code MUST follow PSR-1.
|
||||
|
||||
* Code MUST use 4 spaces for indenting, not tabs.
|
||||
|
||||
* There MUST NOT be a hard limit on line length; the soft limit MUST be 120 characters; lines SHOULD be 80 characters or less.
|
||||
|
||||
* There MUST be one blank line after the `namespace` declaration, and there MUST be one blank line after the block of `use` declarations.
|
||||
|
||||
* Opening braces for classes MUST go on the next line, and closing braces MUST go on the next line after the body.
|
||||
|
||||
* Opening braces for methods MUST go on the next line, and closing braces MUST go on the next line after the body.
|
||||
|
||||
* Visibility MUST be declared on all properties and methods; `abstract` and `final` MUST be declared before the visibility; `static` MUST be declared after the visibility.
|
||||
|
||||
* Control structure keywords MUST have one space after them; method and function calls MUST NOT.
|
||||
|
||||
* Opening braces for control structures MUST go on the same line, and closing braces MUST go on the next line after the body.
|
||||
|
||||
* Opening parentheses for control structures MUST NOT have a space after them, and closing parentheses for control structures MUST NOT have a space before.
|
||||
|
||||
You can read details on [PHP FIG website](http://www.php-fig.org/psr/psr-2/).
|
||||
58
README.md
@ -1,57 +1,9 @@
|
||||
# poche
|
||||
Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is open source.
|
||||
# what is wallabag ?
|
||||
wallabag is a self hostable application allowing you to not miss any content anymore. Click, save, read it when you can. It extracts content so that you can read it when you have time.
|
||||
|
||||

|
||||
|
||||
The website of poche is [inthepoche.com](http://inthepoche.com).
|
||||
|
||||
To test poche, a demo website is online : [demo.inthepoche.com](http://demo.inthepoche.com) (login poche, password poche).
|
||||
|
||||
To get news from poche, [follow us on twitter](http://twitter.com/getpoche) or [read the poche blog](http://inthepoche.com/blog). A Google Group is also available : [poche-users](https://groups.google.com/forum/#!forum/poche-users).
|
||||
|
||||
[](http://flattr.com/thing/1265480/poche-a-read-it-later-open-source-system)
|
||||
|
||||
## Usage
|
||||
You can easily add a "poched" page with the bookmarklet.
|
||||
|
||||
poche save the entire content of a poched links : text and pictures are stored on your server.
|
||||
|
||||
You can :
|
||||
* read a page in a comfortable reading view
|
||||
* archive a link
|
||||
* put a link in favorite
|
||||
* delete a link
|
||||
|
||||
## Requirements & installation
|
||||
You have to install [sqlite for php](http://www.php.net/manual/en/book.sqlite.php) on your server.
|
||||
|
||||
Get the [latest version](https://github.com/inthepoche/poche) of poche on github. Unzip it and upload it on your server. poche must have write access on assets, cache and db directories.
|
||||
|
||||
That's all, **poche works** !
|
||||
|
||||
## Security
|
||||
You **have** to protect your db/poche.sqlite file. Modify the virtual host of your website to add this condition :
|
||||
```apache
|
||||
<Files ~ "\.sqlite$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Files>
|
||||
```
|
||||
|
||||
Nginx version:
|
||||
```nginx
|
||||
location ~ /(db) {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
```
|
||||
|
||||
## Import from Pocket
|
||||
|
||||
If you want to import your Pocket datas, [export them here](https://getpocket.com/export). Put the HTML file in your poche directory, execute import.php file locally by following instructions. Be careful, the script can take a very long time.
|
||||
More informations on our website: [wallabag.org](http://wallabag.org)
|
||||
|
||||
## License
|
||||
Copyright © 2010-2013 Nicolas Lœuillet <nicolas@loeuillet.org>
|
||||
Copyright © 2013-2014 Nicolas Lœuillet <nicolas@loeuillet.org>
|
||||
This work is free. You can redistribute it and/or modify it under the
|
||||
terms of the Do What The Fuck You Want To Public License, Version 2,
|
||||
as published by Sam Hocevar. See the COPYING file for more details.
|
||||
terms of the MIT License. See the COPYING file for more details.
|
||||
|
||||
67
TRANSLATION.md
Executable file
@ -0,0 +1,67 @@
|
||||
# How to manage translations for wallabag
|
||||
|
||||
This guide will describe the procedure of translation management of the wallabag web application.
|
||||
|
||||
All translations are made using [gettext](http://en.wikipedia.org/wiki/Gettext) system and tools.
|
||||
|
||||
You will need the [Poedit](http://www.poedit.net/download.php) editor to update, edit and create your translation files easily. However, you can also handle translations also without it: all can be done using gettext tools and your favorite plain text editor only. This guide, however, describes editing with Poedit. If you want to use gettext only, please refer to the xgettext manual page to update po files from sources (see also how it is used by Poedit below) and use msgunfmt tool to compile .mo files manually.
|
||||
|
||||
You need to know, that translation phrases are stored in **".po"** files (for example: `locale/pl_PL.utf8/LC_MESSAGES/pl_PL.utf8.po`), which are then complied in **".mo"** files using **msgfmt** gettext tool or by Poedit, which will run msgfmt for you in background.
|
||||
|
||||
**It's assumed, that you have wallabag installed locally on your computer or on the server you have access to.**
|
||||
|
||||
## To change existing translation you will need to do:
|
||||
|
||||
### 1. Clear cache
|
||||
You can do this using **http://your-wallabag-host.com/?empty-cache** link (replace http://your-wallabag-host.com/ with real url of your wallabag application)
|
||||
|
||||
OR
|
||||
|
||||
from command line:
|
||||
go to root of your installation of wallabag project and run next command:
|
||||
|
||||
`rm -rf ./cache/*`
|
||||
|
||||
(this may require root privileges if you run, for example Apache web server with mod_php)
|
||||
|
||||
### 2. Generate php files from all twig templates
|
||||
Do this using next command:
|
||||
|
||||
`php ./locale/tools/fillCache.php`
|
||||
|
||||
OR
|
||||
|
||||
from your browser: **http://your-wallabag-host.com/locale/tools/fillCache.php** (this may require removal of .htaccess file in locale/ directory).
|
||||
|
||||
### 3. Configure your Poedit
|
||||
Open Poedit editor, open Edit->Preferences. Go to "Parsers" tab, click on PHP and press "Edit" button. Make sure your "Parser command:" looks like
|
||||
|
||||
`xgettext --no-location --force-po -o %o %C %K %F`
|
||||
|
||||
Usually it is required to add "--no-location" to default value.
|
||||
|
||||
### 4. Open .po file you want to edit in Poedit and change its settings
|
||||
Open, for example `locale/pl_PL.utf8/LC_MESSAGES/pl_PL.utf8.po` file in your Poedit.
|
||||
|
||||
Go to "Catalog"->"Settings..." menu. Then go to "Path" tab and add path to wallabag installation in your local file system. This step can't be omitted as you will not be able to update phrases otherwise.
|
||||
|
||||
You can also check "project into" tab to be sure, that "Language" is set correctly (this will allow you to spell check your translation).
|
||||
|
||||
### 5. Update opened .po file from sources
|
||||
Once you have set your path correctly, you are able to update phrases from sources. Press "Update catalog - synchronize it with sources" button or go to "Catalog"->"Update from sources" menu.
|
||||
|
||||
As a result you will see confirmation popup with two tabs: "New strings" and "Obsolete strings". Please review and accept changes (or press "Undo" if you see too many obsolete strings, as Poedit will remove them all - in this case please make sure all previous steps are performed w/o errors).
|
||||
|
||||
### 6. Translate and save your .po file
|
||||
If you have any difficulties on this step, please consult with Poedit manual.
|
||||
Every time you save your .po file, Poedit will also compile appropriate .mo file by default (of course, if not disabled in preferences).
|
||||
|
||||
You are now almost done.
|
||||
|
||||
### 7. Clear cache again
|
||||
This step may be required if your web server runs php scripts in name of, say, www user (i.e. Apache with mod_php, not cgi).
|
||||
|
||||
|
||||
##To create new translation
|
||||
You just have to copy the folder corresponding to the language you want to translate from, change language in the project settings and for the folder and files names. Then start replacing all existing translations with your own.
|
||||
|
||||
71
Vagrantfile
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
$script_sqlite = <<SCRIPT
|
||||
apt-get update
|
||||
apt-get install -y apache2 php5 php5-sqlite php5-xdebug
|
||||
apt-get clean -y
|
||||
echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
service apache2 restart
|
||||
rm -f /var/www/html/index.html
|
||||
date > /etc/vagrant_provisioned_at
|
||||
SCRIPT
|
||||
|
||||
$script_mysql = <<SCRIPT
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y apache2 php5 php5-mysql php5-xdebug mysql-server mysql-client
|
||||
apt-get clean -y
|
||||
echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
service apache2 restart
|
||||
service mysql restart
|
||||
echo "create database wallabag;" | mysql -u root
|
||||
rm -f /var/www/html/index.html
|
||||
date > /etc/vagrant_provisioned_at
|
||||
SCRIPT
|
||||
|
||||
$script_postgres = <<SCRIPT
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -y apache2 php5 php5-pgsql php5-xdebug postgresql postgresql-contrib
|
||||
apt-get clean -y
|
||||
echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
service apache2 restart
|
||||
service postgresql restart
|
||||
rm -f /var/www/html/index.html
|
||||
date > /etc/vagrant_provisioned_at
|
||||
SCRIPT
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
|
||||
config.vm.define "sqlite" do |m|
|
||||
m.vm.box = "ubuntu/trusty64"
|
||||
m.vm.provision "shell", inline: $script_sqlite
|
||||
m.vm.synced_folder ".", "/var/www/html", owner: "www-data", group: "www-data"
|
||||
end
|
||||
|
||||
config.vm.define "mysql" do |m|
|
||||
m.vm.box = "ubuntu/trusty64"
|
||||
m.vm.provision "shell", inline: $script_mysql
|
||||
m.vm.synced_folder ".", "/var/www/html", owner: "www-data", group: "www-data"
|
||||
end
|
||||
|
||||
config.vm.define "postgres" do |m|
|
||||
m.vm.box = "ubuntu/trusty64"
|
||||
m.vm.provision "shell", inline: $script_postgres
|
||||
m.vm.synced_folder ".", "/var/www/html", owner: "www-data", group: "www-data"
|
||||
end
|
||||
|
||||
config.vm.define "debian7" do |m|
|
||||
m.vm.box = "chef/debian-7.6"
|
||||
m.vm.provision "shell", inline: $script_sqlite
|
||||
m.vm.synced_folder ".", "/var/www", owner: "www-data", group: "www-data"
|
||||
end
|
||||
|
||||
config.vm.define "debian6" do |m|
|
||||
m.vm.box = "chef/debian-6.0.10"
|
||||
m.vm.provision "shell", inline: $script_sqlite
|
||||
m.vm.synced_folder ".", "/var/www", owner: "www-data", group: "www-data"
|
||||
end
|
||||
|
||||
config.vm.network :forwarded_port, guest: 80, host: 8003
|
||||
#config.vm.network "public_network", :bridge => "en0: Wi-Fi (AirPort)"
|
||||
end
|
||||
0
assets/.gitignore
vendored
Executable file
2
cache/.gitignore
vendored
@ -1 +1 @@
|
||||
*
|
||||
!.htaccess
|
||||
|
||||
2
cache/.htaccess
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
14
check_essentials.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
// PHP 5.3 minimum
|
||||
if (version_compare(PHP_VERSION, '5.3.3', '<')) {
|
||||
die('This software require PHP 5.3.3 minimum');
|
||||
}
|
||||
|
||||
// Short tags must be enabled for PHP < 5.4
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '<')) {
|
||||
|
||||
if (! ini_get('short_open_tag')) {
|
||||
die('This software require to have short tags enabled, check your php.ini => "short_open_tag = On"');
|
||||
}
|
||||
}
|
||||
12
check_setup.php
Executable file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// Check if /cache is writeable
|
||||
if (! is_writable('cache')) {
|
||||
die('The directory "cache" must be writeable by your web server user');
|
||||
}
|
||||
|
||||
// install folder still present, need to install wallabag
|
||||
if (is_dir('install')) {
|
||||
require('install/index.php');
|
||||
exit;
|
||||
}
|
||||
7
composer.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"require": {
|
||||
"twig/twig": "1.*",
|
||||
"twig/extensions": "1.0.*",
|
||||
"umpirsky/twig-gettext-extractor": "1.1.*"
|
||||
}
|
||||
}
|
||||
744
composer.lock
generated
Normal file
@ -0,0 +1,744 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
|
||||
],
|
||||
"hash": "1c8badb14d91f4f3ef1cfae23252a2c4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/http-kernel": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\EventDispatcher\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-05-13 14:36:40"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/Filesystem",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Filesystem.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Filesystem\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-06-04 15:02:05"
|
||||
},
|
||||
{
|
||||
"name": "symfony/form",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/Form",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Form.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Form/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/event-dispatcher": "~2.1",
|
||||
"symfony/intl": "~2.3",
|
||||
"symfony/options-resolver": "~2.1",
|
||||
"symfony/property-access": "~2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/http-foundation": "~2.2",
|
||||
"symfony/validator": "~2.2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/http-foundation": "",
|
||||
"symfony/validator": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Form\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Form Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-07-01 12:24:43"
|
||||
},
|
||||
{
|
||||
"name": "symfony/icu",
|
||||
"version": "v1.0.0",
|
||||
"target-dir": "Symfony/Component/Icu",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Icu.git",
|
||||
"reference": "v1.0.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Icu/zipball/v1.0.0",
|
||||
"reference": "v1.0.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/intl": ">=2.3,<3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Icu\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Contains an excerpt of the ICU data and classes to load it.",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"icu",
|
||||
"intl"
|
||||
],
|
||||
"time": "2013-06-03 18:32:07"
|
||||
},
|
||||
{
|
||||
"name": "symfony/intl",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/Intl",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Intl.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/icu": "~1.0-RC"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/filesystem": ">=2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "to use the component with locales other than \"en\""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Intl\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Symfony/Component/Intl/Resources/stubs"
|
||||
],
|
||||
"files": [
|
||||
"Symfony/Component/Intl/Resources/stubs/functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Igor Wiedler",
|
||||
"email": "igor@wiedler.ch",
|
||||
"homepage": "http://wiedler.ch/igor/"
|
||||
},
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Eriksen Costa",
|
||||
"email": "eriksen.costa@infranology.com.br"
|
||||
}
|
||||
],
|
||||
"description": "A PHP replacement layer for the C intl extension that includes additional data from the ICU library.",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"i18n",
|
||||
"icu",
|
||||
"internationalization",
|
||||
"intl",
|
||||
"l10n",
|
||||
"localization"
|
||||
],
|
||||
"time": "2013-07-08 13:00:35"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/OptionsResolver",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/OptionsResolver.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\OptionsResolver\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony OptionsResolver Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"config",
|
||||
"configuration",
|
||||
"options"
|
||||
],
|
||||
"time": "2013-04-11 06:50:46"
|
||||
},
|
||||
{
|
||||
"name": "symfony/property-access",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/PropertyAccess",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/PropertyAccess.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\PropertyAccess\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony PropertyAccess Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"access",
|
||||
"array",
|
||||
"extraction",
|
||||
"index",
|
||||
"injection",
|
||||
"object",
|
||||
"property",
|
||||
"property path",
|
||||
"reflection"
|
||||
],
|
||||
"time": "2013-07-01 12:24:43"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/Routing",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Routing.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/common": "~2.2",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "~2.2",
|
||||
"symfony/yaml": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/common": "",
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Routing\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Routing Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-06-23 08:16:02"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Component/Translation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Translation.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "~2.0",
|
||||
"symfony/yaml": "~2.2"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Translation\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-05-13 14:36:40"
|
||||
},
|
||||
{
|
||||
"name": "symfony/twig-bridge",
|
||||
"version": "v2.3.2",
|
||||
"target-dir": "Symfony/Bridge/Twig",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/TwigBridge.git",
|
||||
"reference": "v2.3.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/TwigBridge/zipball/v2.3.2",
|
||||
"reference": "v2.3.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"twig/twig": "~1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/form": "2.2.*",
|
||||
"symfony/http-kernel": "~2.2",
|
||||
"symfony/routing": "~2.2",
|
||||
"symfony/security": "~2.0",
|
||||
"symfony/templating": "~2.1",
|
||||
"symfony/translation": "~2.2",
|
||||
"symfony/yaml": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/form": "",
|
||||
"symfony/http-kernel": "",
|
||||
"symfony/routing": "",
|
||||
"symfony/security": "",
|
||||
"symfony/templating": "",
|
||||
"symfony/translation": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "symfony-bridge",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Bridge\\Twig\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Twig Bridge",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-05-16 10:19:58"
|
||||
},
|
||||
{
|
||||
"name": "twig/extensions",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig-extensions.git",
|
||||
"reference": "v1.0.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig-extensions/zipball/v1.0.0",
|
||||
"reference": "v1.0.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"twig/twig": "1.*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_Extensions_": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Common additional features for Twig that do not directly belong in core",
|
||||
"homepage": "https://github.com/fabpot/Twig-extensions",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"i18n",
|
||||
"text"
|
||||
],
|
||||
"time": "2013-02-28 14:21:30"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.13.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig.git",
|
||||
"reference": "v1.13.2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.13.2",
|
||||
"reference": "v1.13.2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.13-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "http://twig.sensiolabs.org",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2013-08-03 15:35:31"
|
||||
},
|
||||
{
|
||||
"name": "umpirsky/twig-gettext-extractor",
|
||||
"version": "1.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/umpirsky/Twig-Gettext-Extractor.git",
|
||||
"reference": "1.1.3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/umpirsky/Twig-Gettext-Extractor/zipball/1.1.3",
|
||||
"reference": "1.1.3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/filesystem": ">=2.0,<3.0",
|
||||
"symfony/form": ">=2.0,<3.0",
|
||||
"symfony/routing": ">=2.0,<3.0",
|
||||
"symfony/translation": ">=2.0,<3.0",
|
||||
"symfony/twig-bridge": ">=2.0,<3.0",
|
||||
"twig/extensions": "1.0.*",
|
||||
"twig/twig": ">=1.2.0,<2.0-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "2.1.*"
|
||||
},
|
||||
"bin": [
|
||||
"twig-gettext-extractor"
|
||||
],
|
||||
"type": "application",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig\\Gettext": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Саша Стаменковић",
|
||||
"email": "umpirsky@gmail.com",
|
||||
"homepage": "http://umpirsky.com"
|
||||
}
|
||||
],
|
||||
"description": "The Twig Gettext Extractor is Poedit friendly tool which extracts translations from twig templates.",
|
||||
"time": "2013-02-14 16:41:48"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [
|
||||
|
||||
],
|
||||
"platform": [
|
||||
|
||||
],
|
||||
"platform-dev": [
|
||||
|
||||
]
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
/*** GENERAL ***/
|
||||
body {
|
||||
color: #fff;
|
||||
background-color: #0d0d0d;
|
||||
}
|
||||
|
||||
a, a:hover, a:visited {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#main ul#links li a.current {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#links a:hover, .backhome a:hover{
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
input[type=submit].delete {
|
||||
background : url('../img/dark/remove.png') no-repeat center center;
|
||||
color : transparent;
|
||||
}
|
||||
|
||||
#main .entrie {
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
#main .entrie h2 a:hover {
|
||||
color: #29B1E3;
|
||||
}
|
||||
|
||||
a.fav span {
|
||||
background: url('../img/dark/star-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav span:hover {
|
||||
background: url('../img/dark/star-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav-off span {
|
||||
background: url('../img/dark/star-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav-off span:hover {
|
||||
background: url('../img/dark/star-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive span {
|
||||
background: url('../img/dark/checkmark-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive span:hover {
|
||||
background: url('../img/dark/checkmark-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive-off span {
|
||||
background: url('../img/dark/checkmark-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive-off span:hover {
|
||||
background: url('../img/dark/checkmark-on.png') no-repeat;
|
||||
}
|
||||
|
||||
/*** ***/
|
||||
/*** ARTICLE PAGE ***/
|
||||
|
||||
body.article {
|
||||
color: #fff;
|
||||
background-color: #0d0d0d;
|
||||
}
|
||||
|
||||
#article header {
|
||||
border-bottom: 1px solid #222222;
|
||||
}
|
||||
|
||||
#article article {
|
||||
border-bottom: 1px solid #222222;
|
||||
}
|
||||
|
||||
.vieworiginal a {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.entrie {
|
||||
background-color: #fff;
|
||||
}
|
||||
@ -1,100 +0,0 @@
|
||||
/*** GENERAL ***/
|
||||
body {
|
||||
color: #222222;
|
||||
background-color: #F1F1F1;
|
||||
}
|
||||
|
||||
a, a:hover, a:visited {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.bouton {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
.bouton:hover {
|
||||
background-color: #222222;
|
||||
color: #F1F1F1;
|
||||
}
|
||||
|
||||
#main ul#links li a.current {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#links a:hover, .backhome a:hover{
|
||||
background-color: #040707;
|
||||
color: #F1F1F1;
|
||||
}
|
||||
|
||||
input[type=submit].delete {
|
||||
background : url('../img/light/remove.png') no-repeat center center;
|
||||
color : transparent;
|
||||
}
|
||||
|
||||
#main .entrie {
|
||||
color: #2e2e2e;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#main .entrie h2 a:hover {
|
||||
color: #F5BE00;
|
||||
}
|
||||
|
||||
a.fav span {
|
||||
background: url('../img/light/star-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav span:hover {
|
||||
background: url('../img/light/star-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav-off span {
|
||||
background: url('../img/light/star-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.fav-off span:hover {
|
||||
background: url('../img/light/star-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive span {
|
||||
background: url('../img/light/checkmark-on.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive span:hover {
|
||||
background: url('../img/light/checkmark-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive-off span {
|
||||
background: url('../img/light/checkmark-off.png') no-repeat;
|
||||
}
|
||||
|
||||
a.archive-off span:hover {
|
||||
background: url('../img/light/checkmark-on.png') no-repeat;
|
||||
}
|
||||
|
||||
/*** ***/
|
||||
/*** ARTICLE PAGE ***/
|
||||
|
||||
body.article {
|
||||
color: #222222;
|
||||
background-color: #F1F1F1;
|
||||
}
|
||||
|
||||
#article header {
|
||||
border-bottom: 1px solid #222222;
|
||||
}
|
||||
|
||||
#article article {
|
||||
border-bottom: 1px solid #222222;
|
||||
}
|
||||
|
||||
.vieworiginal a {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.entrie {
|
||||
background-color: #fff;
|
||||
}
|
||||
215
css/style.css
@ -1,215 +0,0 @@
|
||||
/*** GENERAL ***/
|
||||
body {
|
||||
font: 20px/1.3em Palatino,Georgia,serif;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bouton {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#main ul#links {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#main ul#links li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#main ul#links li a.current {
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#main ul#sort {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#main ul#sort li {
|
||||
display: inline;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
#main ul#sort img:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#main, #article {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#links a, .backhome a{
|
||||
text-decoration: none;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#links a:hover, .backhome a:hover{
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*** ***/
|
||||
/*** LINKS DISPLAY ***/
|
||||
|
||||
#main a.tool {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type=submit].delete {
|
||||
width : 16px;
|
||||
height :16px;
|
||||
border : none;
|
||||
cursor: pointer;
|
||||
font-size : 0;
|
||||
}
|
||||
|
||||
#main #content {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#main .entrie {
|
||||
padding: 15px;
|
||||
min-height: 8em;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
#main .entrie h2 a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tools {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tools ul {
|
||||
padding: 0; margin: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.tools ul li {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.tools a.tool {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#article .tools {
|
||||
position: relative;
|
||||
display: inline;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#article .tools ul li{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#main .entrie .tools a.tool span, #article .tools a.tool span {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
|
||||
/*** ***/
|
||||
/*** ARTICLE PAGE ***/
|
||||
|
||||
body.article {
|
||||
font: 20px/1.3em Palatino,Georgia,serif;
|
||||
}
|
||||
|
||||
#article header {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#article header a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.vieworiginal a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.backhome {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/*** ***/
|
||||
|
||||
#main
|
||||
{
|
||||
max-width: 60em; /* 960 px */
|
||||
margin: 0 auto;
|
||||
}
|
||||
#content
|
||||
{
|
||||
width: 103.125%; /* 990px */
|
||||
overflow: hidden;
|
||||
margin-left: -1.562%; /* 15px */
|
||||
margin-bottom: -1.875em; /* 30px */
|
||||
}
|
||||
|
||||
.entrie
|
||||
{
|
||||
width: 30.303%; /* 300px */
|
||||
background-color: #fff;
|
||||
float: left;
|
||||
margin: 0 1.515% 1.875em; /* 15px 30px */
|
||||
}
|
||||
|
||||
@media only screen and ( max-width: 40em ) /* 640px */
|
||||
{
|
||||
.entrie
|
||||
{
|
||||
width: 46.876%; /* 305px */
|
||||
margin-bottom: 0.938em; /* 15px */
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and ( max-width: 20em ) /* 320px */
|
||||
{
|
||||
#content
|
||||
{
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.entrie
|
||||
{
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*** ***/
|
||||
/*** MESSAGES ***/
|
||||
|
||||
.messages { width: 100%; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }
|
||||
.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }
|
||||
/*.messages:hover a.closeMessage { visibility:visible; }*/
|
||||
.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }
|
||||
.messages.error { border: 1px solid #C42608; color: #c00 !important; background: #FFF0EF; }
|
||||
.messages.error p { background: url(../img/messages/cross.png ) no-repeat 0px 50%; color:#c00 !important; }
|
||||
.messages.success {background: #E0FBCC; border: 1px solid #6DC70C; }
|
||||
.messages.success p { background: url(../img/messages/tick.png) no-repeat 0px 50%; color: #2B6301 !important; }
|
||||
.messages.warning { background: #FFFCD3; border: 1px solid #EBCD41; color: #000; }
|
||||
.messages.warning p { background: url(../img/messages/warning.png ) no-repeat 0px 50%; color: #5F4E01; }
|
||||
.messages.information, .messages.info { background: #DFEBFB; border: 1px solid #82AEE7; }
|
||||
.messages.information p, .messages.info p { background: url(../img/messages/help.png ) no-repeat 0px 50%; color: #064393; }
|
||||
.messages.information a { text-decoration: underline; }
|
||||
0
db/.gitignore
vendored
Normal file
2
db/.htaccess
Normal file
@ -0,0 +1,2 @@
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
BIN
db/poche.sqlite
|
Before Width: | Height: | Size: 267 B |
|
Before Width: | Height: | Size: 221 B |
|
Before Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 786 B |
|
Before Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 277 B |
BIN
img/dark/up.png
|
Before Width: | Height: | Size: 225 B |
BIN
img/logo.png
|
Before Width: | Height: | Size: 911 B |
50
import.php
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* poche, a read it later open source system
|
||||
*
|
||||
* @category poche
|
||||
* @author Nicolas Lœuillet <support@inthepoche.com>
|
||||
* @copyright 2013
|
||||
* @license http://www.wtfpl.net/ see COPYING file
|
||||
*/
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
include dirname(__FILE__).'/inc/config.php';
|
||||
include dirname(__FILE__).'/inc/simple_html_dom.php';
|
||||
|
||||
if (!isset($_GET['start'])) {
|
||||
echo 'Please execute the import script locally, it can take a very long time. <br /><a href="import.php?start">Bye bye Pocket, let\'s go !</a>';
|
||||
}
|
||||
else {
|
||||
$html = new simple_html_dom();
|
||||
$html->load_file('ril_export.html');
|
||||
|
||||
$read = 0;
|
||||
$errors = array();
|
||||
foreach($html->find('ul') as $ul)
|
||||
{
|
||||
foreach($ul->find('li') as $li)
|
||||
{
|
||||
$a = $li->find('a');
|
||||
$url = $a[0]->href;
|
||||
|
||||
|
||||
action_to_do('add', $url);
|
||||
if ($read == '1') {
|
||||
$last_id = $db->getHandle()->lastInsertId();
|
||||
$sql_update = "UPDATE entries SET is_read=~is_read WHERE id=?";
|
||||
$params_update = array($last_id);
|
||||
$query_update = $db->getHandle()->prepare($sql_update);
|
||||
$query_update->execute($params_update);
|
||||
}
|
||||
}
|
||||
# Pocket génère un fichier HTML avec deux <ul>
|
||||
# Le premier concerne les éléments non lus
|
||||
# Le second concerne les éléments archivés
|
||||
$read = 1;
|
||||
}
|
||||
|
||||
echo 'Import from Pocket completed. <a href="index.php">Welcome to #poche !</a>';
|
||||
logm('import from pocket completed');
|
||||
}
|
||||
57
inc/3rdparty/FlattrItem.class.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* wallabag, self hostable application allowing you to not miss any content anymore
|
||||
*
|
||||
* @category wallabag
|
||||
* @author Nicolas Lœuillet <nicolas@loeuillet.org>
|
||||
* @copyright 2013
|
||||
* @license http://opensource.org/licenses/MIT see COPYING file
|
||||
*/
|
||||
|
||||
class FlattrItem
|
||||
{
|
||||
public $status;
|
||||
public $urlToFlattr;
|
||||
public $flattrItemURL;
|
||||
public $numFlattrs;
|
||||
|
||||
public function checkItem($urlToFlattr, $id)
|
||||
{
|
||||
$this->_cacheFlattrFile($urlToFlattr, $id);
|
||||
$flattrResponse = file_get_contents(CACHE . "/flattr/".$id.".cache");
|
||||
if($flattrResponse != FALSE) {
|
||||
$result = json_decode($flattrResponse);
|
||||
if (isset($result->message)) {
|
||||
if ($result->message == "flattrable") {
|
||||
$this->status = FLATTRABLE;
|
||||
}
|
||||
}
|
||||
elseif (is_object($result) && $result->link) {
|
||||
$this->status = FLATTRED;
|
||||
$this->flattrItemURL = $result->link;
|
||||
$this->numFlattrs = $result->flattrs;
|
||||
}
|
||||
else {
|
||||
$this->status = NOT_FLATTRABLE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->status = "FLATTR_ERR_CONNECTION";
|
||||
}
|
||||
}
|
||||
|
||||
private function _cacheFlattrFile($urlToFlattr, $id)
|
||||
{
|
||||
if (!is_dir(CACHE . '/flattr')) {
|
||||
mkdir(CACHE . '/flattr', 0777);
|
||||
}
|
||||
|
||||
// if a cache flattr file for this url already exists and it's been less than one day than it have been updated, see in /cache
|
||||
if ((!file_exists(CACHE . "/flattr/".$id.".cache")) || (time() - filemtime(CACHE . "/flattr/".$id.".cache") > 86400)) {
|
||||
$askForFlattr = Tools::getFile(FLATTR_API . $urlToFlattr);
|
||||
$flattrCacheFile = fopen(CACHE . "/flattr/".$id.".cache", 'w+');
|
||||
fwrite($flattrCacheFile, $askForFlattr);
|
||||
fclose($flattrCacheFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
346
inc/3rdparty/Session.class.php
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* Session management class
|
||||
*
|
||||
* http://www.developpez.net/forums/d51943/php/langage/sessions/
|
||||
* http://sebsauvage.net/wiki/doku.php?id=php:session
|
||||
* http://sebsauvage.net/wiki/doku.php?id=php:shaarli
|
||||
*
|
||||
* Features:
|
||||
* - Everything is stored on server-side (we do not trust client-side data,
|
||||
* such as cookie expiration)
|
||||
* - IP addresses are checked on each access to prevent session cookie hijacking
|
||||
* (such as Firesheep)
|
||||
* - Session expires on user inactivity (Session expiration date is
|
||||
* automatically updated everytime the user accesses a page.)
|
||||
* - A unique secret key is generated on server-side for this session
|
||||
* (and never sent over the wire) which can be used to sign forms (HMAC)
|
||||
* (See $_SESSION['uid'])
|
||||
* - Token management to prevent XSRF attacks
|
||||
* - Brute force protection with ban management
|
||||
*
|
||||
* TODOs
|
||||
* - Replace globals with variables in Session class
|
||||
*
|
||||
* How to use:
|
||||
* - http://tontof.net/kriss/php5/session
|
||||
*/
|
||||
class Session
|
||||
{
|
||||
// Personnalize PHP session name
|
||||
public static $sessionName = '';
|
||||
// If the user does not access any page within this time,
|
||||
// his/her session is considered expired (3600 sec. = 1 hour)
|
||||
public static $inactivityTimeout = 3600;
|
||||
// Extra timeout for long sessions (if enabled) (82800 sec. = 23 hours)
|
||||
public static $longSessionTimeout = 7776000; // 7776000 = 90 days
|
||||
// If you get disconnected often or if your IP address changes often.
|
||||
// Let you disable session cookie hijacking protection
|
||||
public static $disableSessionProtection = false;
|
||||
// Ban IP after this many failures.
|
||||
public static $banAfter = 4;
|
||||
// Ban duration for IP address after login failures (in seconds).
|
||||
// (1800 sec. = 30 minutes)
|
||||
public static $banDuration = 1800;
|
||||
// File storage for failures and bans. If empty, no ban management.
|
||||
public static $banFile = '';
|
||||
|
||||
/**
|
||||
* Initialize session
|
||||
*/
|
||||
public static function init($longlastingsession = false)
|
||||
{
|
||||
//check if session name is correct
|
||||
if ( (session_id() && !empty(self::$sessionName) && session_name()!=self::$sessionName) || $longlastingsession ) {
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
// Force cookie path (but do not change lifetime)
|
||||
$cookie = session_get_cookie_params();
|
||||
// Default cookie expiration and path.
|
||||
$cookiedir = '';
|
||||
if (dirname($_SERVER['SCRIPT_NAME'])!='/') {
|
||||
$cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/';
|
||||
}
|
||||
$ssl = false;
|
||||
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
|
||||
$ssl = true;
|
||||
}
|
||||
|
||||
if ( $longlastingsession ) {
|
||||
session_set_cookie_params(self::$longSessionTimeout, $cookiedir, null, $ssl, true);
|
||||
}
|
||||
else {
|
||||
session_set_cookie_params(0, $cookiedir, null, $ssl, true);
|
||||
}
|
||||
//set server side valid session timeout
|
||||
//WARNING! this may not work in shared session environment. See http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime about min value: it can be set in any application
|
||||
ini_set('session.gc_maxlifetime', self::$longSessionTimeout);
|
||||
|
||||
// Use cookies to store session.
|
||||
ini_set('session.use_cookies', 1);
|
||||
// Force cookies for session (phpsessionID forbidden in URL)
|
||||
ini_set('session.use_only_cookies', 1);
|
||||
if ( !session_id() ) {
|
||||
// Prevent php to use sessionID in URL if cookies are disabled.
|
||||
ini_set('session.use_trans_sid', false);
|
||||
if (!empty(self::$sessionName)) {
|
||||
session_name(self::$sessionName);
|
||||
}
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP address
|
||||
* (Used to prevent session cookie hijacking.)
|
||||
*
|
||||
* @return string IP addresses
|
||||
*/
|
||||
private static function _allIPs()
|
||||
{
|
||||
$ip = $_SERVER["REMOTE_ADDR"];
|
||||
$ip.= isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? '_'.$_SERVER['HTTP_X_FORWARDED_FOR'] : '';
|
||||
$ip.= isset($_SERVER['HTTP_CLIENT_IP']) ? '_'.$_SERVER['HTTP_CLIENT_IP'] : '';
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that user/password is correct and then init some SESSION variables.
|
||||
*
|
||||
* @param string $login Login reference
|
||||
* @param string $password Password reference
|
||||
* @param string $loginTest Login to compare with login reference
|
||||
* @param string $passwordTest Password to compare with password reference
|
||||
* @param array $pValues Array of variables to store in SESSION
|
||||
*
|
||||
* @return true|false True if login and password are correct, false
|
||||
* otherwise
|
||||
*/
|
||||
public static function login (
|
||||
$login,
|
||||
$password,
|
||||
$loginTest,
|
||||
$passwordTest,
|
||||
$longlastingsession,
|
||||
$pValues = array())
|
||||
{
|
||||
self::banInit();
|
||||
if (self::banCanLogin()) {
|
||||
if ($login === $loginTest && $password === $passwordTest) {
|
||||
self::banLoginOk();
|
||||
|
||||
self::init($longlastingsession);
|
||||
|
||||
// Generate unique random number to sign forms (HMAC)
|
||||
$_SESSION['uid'] = sha1(uniqid('', true).'_'.mt_rand());
|
||||
$_SESSION['ip'] = self::_allIPs();
|
||||
$_SESSION['username'] = $login;
|
||||
// Set session expiration.
|
||||
$_SESSION['expires_on'] = time() + self::$inactivityTimeout;
|
||||
if ($longlastingsession) {
|
||||
$_SESSION['longlastingsession'] = self::$longSessionTimeout;
|
||||
$_SESSION['expires_on'] += $_SESSION['longlastingsession'];
|
||||
}
|
||||
|
||||
foreach ($pValues as $key => $value) {
|
||||
$_SESSION[$key] = $value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
self::banLoginFailed();
|
||||
}
|
||||
|
||||
self::init();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset SESSION variable to force logout
|
||||
*/
|
||||
public static function logout()
|
||||
{
|
||||
// unset($_SESSION['uid'],$_SESSION['ip'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass'], $_SESSION['longlastingsession'], $_SESSION['poche_user']);
|
||||
|
||||
// Destruction du cookie (le code peut paraître complexe mais c'est pour être certain de reprendre les mêmes paramètres)
|
||||
$args = array_merge(array(session_name(), ''), array_values(session_get_cookie_params()));
|
||||
$args[2] = time() - 3600;
|
||||
call_user_func_array('setcookie', $args);
|
||||
// Suppression physique de la session
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure user is logged in.
|
||||
*
|
||||
* @return true|false True if user is logged in, false otherwise
|
||||
*/
|
||||
public static function isLogged()
|
||||
{
|
||||
if (!isset ($_SESSION['uid'])
|
||||
|| (self::$disableSessionProtection === false
|
||||
&& $_SESSION['ip'] !== self::_allIPs())
|
||||
|| time() >= $_SESSION['expires_on']) {
|
||||
//self::logout();
|
||||
|
||||
return false;
|
||||
}
|
||||
// User accessed a page : Update his/her session expiration date.
|
||||
$_SESSION['expires_on'] = time() + self::$inactivityTimeout;
|
||||
if (!empty($_SESSION['longlastingsession'])) {
|
||||
$_SESSION['expires_on'] += $_SESSION['longlastingsession'];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a token, store it in SESSION and return it
|
||||
*
|
||||
* @param string $salt to prevent birthday attack
|
||||
*
|
||||
* @return string Token created
|
||||
*/
|
||||
public static function getToken($salt = '')
|
||||
{
|
||||
if (!isset($_SESSION['tokens'])) {
|
||||
$_SESSION['tokens']=array();
|
||||
}
|
||||
// We generate a random string and store it on the server side.
|
||||
$rnd = sha1(uniqid('', true).'_'.mt_rand().$salt);
|
||||
$_SESSION['tokens'][$rnd]=1;
|
||||
|
||||
return $rnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if a token is ok. Using this function will destroy the token.
|
||||
*
|
||||
* @param string $token Token to test
|
||||
*
|
||||
* @return true|false True if token is correct, false otherwise
|
||||
*/
|
||||
public static function isToken($token)
|
||||
{
|
||||
if (isset($_SESSION['tokens'][$token])) {
|
||||
unset($_SESSION['tokens'][$token]); // Token is used: destroy it.
|
||||
|
||||
return true; // Token is ok.
|
||||
}
|
||||
|
||||
return false; // Wrong token, or already used.
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal a failed login. Will ban the IP if too many failures:
|
||||
*/
|
||||
public static function banLoginFailed()
|
||||
{
|
||||
if (self::$banFile !== '') {
|
||||
$ip = $_SERVER["REMOTE_ADDR"];
|
||||
$gb = $GLOBALS['IPBANS'];
|
||||
|
||||
if (!isset($gb['FAILURES'][$ip])) {
|
||||
$gb['FAILURES'][$ip] = 0;
|
||||
}
|
||||
$gb['FAILURES'][$ip]++;
|
||||
if ($gb['FAILURES'][$ip] > (self::$banAfter - 1)) {
|
||||
$gb['BANS'][$ip]= time() + self::$banDuration;
|
||||
}
|
||||
|
||||
$GLOBALS['IPBANS'] = $gb;
|
||||
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals a successful login. Resets failed login counter.
|
||||
*/
|
||||
public static function banLoginOk()
|
||||
{
|
||||
if (self::$banFile !== '') {
|
||||
$ip = $_SERVER["REMOTE_ADDR"];
|
||||
$gb = $GLOBALS['IPBANS'];
|
||||
unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]);
|
||||
$GLOBALS['IPBANS'] = $gb;
|
||||
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ban init
|
||||
*/
|
||||
public static function banInit()
|
||||
{
|
||||
if (self::$banFile !== '') {
|
||||
if (!is_file(self::$banFile)) {
|
||||
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export(array('FAILURES'=>array(), 'BANS'=>array()), true).";\n?>");
|
||||
}
|
||||
include self::$banFile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user CAN login. If 'true', the user can try to login.
|
||||
*
|
||||
* @return boolean true if user is banned, false otherwise
|
||||
*/
|
||||
public static function banCanLogin()
|
||||
{
|
||||
if (self::$banFile !== '') {
|
||||
$ip = $_SERVER["REMOTE_ADDR"];
|
||||
$gb = $GLOBALS['IPBANS'];
|
||||
if (isset($gb['BANS'][$ip])) {
|
||||
// User is banned. Check if the ban has expired:
|
||||
if ($gb['BANS'][$ip] <= time()) {
|
||||
// Ban expired, user can try to login again.
|
||||
unset($gb['FAILURES'][$ip]);
|
||||
unset($gb['BANS'][$ip]);
|
||||
file_put_contents(self::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
|
||||
|
||||
return true; // Ban has expired, user can login.
|
||||
}
|
||||
|
||||
return false; // User is banned.
|
||||
}
|
||||
}
|
||||
|
||||
return true; // User is not banned.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells if a param exists in session
|
||||
*
|
||||
* @param $name name of the param to test
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInSession($name)
|
||||
{
|
||||
return (isset($_SESSION[$name]) ? : FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns param in session
|
||||
*
|
||||
* @param $name name of the param to return
|
||||
* @return mixed param or null
|
||||
*/
|
||||
public static function getParam($name)
|
||||
{
|
||||
return (self::isInSession($name) ? $_SESSION[$name] : NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store value in session
|
||||
*
|
||||
* @param $name name of the variable to store
|
||||
* @param $value value to store
|
||||
*/
|
||||
public static function setParam($name, $value)
|
||||
{
|
||||
$_SESSION[$name] = $value;
|
||||
}
|
||||
}
|
||||
@ -1,231 +1,232 @@
|
||||
<?php
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Session-Based Flash Messages v1.0
|
||||
// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
// Description:
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Stores messages in Session data to be easily retrieved later on.
|
||||
// This class includes four different types of messages:
|
||||
// - Success
|
||||
// - Error
|
||||
// - Warning
|
||||
// - Information
|
||||
//
|
||||
// See README for basic usage instructions, or see samples/index.php for more advanced samples
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Changelog
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// 2011-05-15 - v1.0 - Initial Version
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
class Messages {
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Class Variables
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
var $msgId;
|
||||
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
|
||||
var $msgClass = 'messages';
|
||||
var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'></a>\n%s</div>\n";
|
||||
var $msgBefore = '<p>';
|
||||
var $msgAfter = "</p>\n";
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @author Mike Everhart
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// Generate a unique ID for this user and session
|
||||
$this->msgId = md5(uniqid());
|
||||
|
||||
// Create the session array if it doesnt already exist
|
||||
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the queue
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of message to add
|
||||
* @param string $message The message
|
||||
* @param string $redirect_to (optional) If set, the user will be redirected to this URL
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function add($type, $message, $redirect_to=null) {
|
||||
|
||||
if( !isset($_SESSION['flash_messages']) ) return false;
|
||||
|
||||
if( !isset($type) || !isset($message[0]) ) return false;
|
||||
|
||||
// Replace any shorthand codes with their full version
|
||||
if( strlen(trim($type)) == 1 ) {
|
||||
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
|
||||
|
||||
// Backwards compatibility...
|
||||
} elseif( $type == 'information' ) {
|
||||
$type = 'info';
|
||||
}
|
||||
|
||||
// Make sure it's a valid message type
|
||||
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
|
||||
|
||||
// If the session array doesn't exist, create it
|
||||
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
|
||||
|
||||
$_SESSION['flash_messages'][$type][] = $message;
|
||||
|
||||
if( !is_null($redirect_to) ) {
|
||||
header("Location: $redirect_to");
|
||||
exit();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// display()
|
||||
// print queued messages to the screen
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Display the queued messages
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type Which messages to display
|
||||
* @param bool $print True = print the messages on the screen
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function display($type='all', $print=true) {
|
||||
$messages = '';
|
||||
$data = '';
|
||||
|
||||
if( !isset($_SESSION['flash_messages']) ) return false;
|
||||
|
||||
if( $type == 'g' || $type == 'growl' ) {
|
||||
$this->displayGrowlMessages();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Print a certain type of message?
|
||||
if( in_array($type, $this->msgTypes) ) {
|
||||
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
|
||||
$messages .= $this->msgBefore . $msg . $this->msgAfter;
|
||||
}
|
||||
|
||||
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
|
||||
|
||||
// Clear the viewed messages
|
||||
$this->clear($type);
|
||||
|
||||
// Print ALL queued messages
|
||||
} elseif( $type == 'all' ) {
|
||||
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
|
||||
$messages = '';
|
||||
foreach( $msgArray as $msg ) {
|
||||
$messages .= $this->msgBefore . $msg . $this->msgAfter;
|
||||
}
|
||||
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
|
||||
}
|
||||
|
||||
// Clear ALL of the messages
|
||||
$this->clear();
|
||||
|
||||
// Invalid Message Type?
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print everything to the screen or return the data
|
||||
if( $print ) {
|
||||
echo $data;
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if there are any queued error messages
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @return bool true = There ARE error messages
|
||||
* false = There are NOT any error messages
|
||||
*
|
||||
*/
|
||||
public function hasErrors() {
|
||||
return empty($_SESSION['flash_messages']['error']) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if there are any ($type) messages queued
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of messages to check for
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function hasMessages($type=null) {
|
||||
if( !is_null($type) ) {
|
||||
if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
|
||||
} else {
|
||||
foreach( $this->msgTypes as $type ) {
|
||||
if( !empty($_SESSION['flash_messages']) ) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear messages from the session data
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of messages to clear
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function clear($type='all') {
|
||||
if( $type == 'all' ) {
|
||||
unset($_SESSION['flash_messages']);
|
||||
} else {
|
||||
unset($_SESSION['flash_messages'][$type]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function __toString() { return $this->hasMessages(); }
|
||||
|
||||
public function __destruct() {
|
||||
//$this->clear();
|
||||
}
|
||||
|
||||
|
||||
} // end class
|
||||
?>
|
||||
<?php
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Session-Based Flash Messages v1.0
|
||||
// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
// Description:
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Stores messages in Session data to be easily retrieved later on.
|
||||
// This class includes four different types of messages:
|
||||
// - Success
|
||||
// - Error
|
||||
// - Warning
|
||||
// - Information
|
||||
//
|
||||
// See README for basic usage instructions, or see samples/index.php for more advanced samples
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Changelog
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// 2011-05-15 - v1.0 - Initial Version
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
class Messages {
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Class Variables
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
var $msgId;
|
||||
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
|
||||
var $msgClass = 'messages';
|
||||
var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'>×</a>\n%s</div>\n";
|
||||
var $msgBefore = '<p>';
|
||||
var $msgAfter = "</p>\n";
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @author Mike Everhart
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// Generate a unique ID for this user and session
|
||||
$this->msgId = md5(uniqid());
|
||||
|
||||
// Create the session array if it doesnt already exist
|
||||
settype($_SESSION, 'array');
|
||||
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the queue
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of message to add
|
||||
* @param string $message The message
|
||||
* @param string $redirect_to (optional) If set, the user will be redirected to this URL
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function add($type, $message, $redirect_to=null) {
|
||||
|
||||
if( !isset($_SESSION['flash_messages']) ) return false;
|
||||
|
||||
if( !isset($type) || !isset($message[0]) ) return false;
|
||||
|
||||
// Replace any shorthand codes with their full version
|
||||
if( strlen(trim($type)) == 1 ) {
|
||||
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
|
||||
|
||||
// Backwards compatibility...
|
||||
} elseif( $type == 'information' ) {
|
||||
$type = 'info';
|
||||
}
|
||||
|
||||
// Make sure it's a valid message type
|
||||
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
|
||||
|
||||
// If the session array doesn't exist, create it
|
||||
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
|
||||
|
||||
$_SESSION['flash_messages'][$type][] = $message;
|
||||
|
||||
if( !is_null($redirect_to) ) {
|
||||
header("Location: $redirect_to");
|
||||
exit();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// display()
|
||||
// print queued messages to the screen
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Display the queued messages
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type Which messages to display
|
||||
* @param bool $print True = print the messages on the screen
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
public function display($type='all', $print=true) {
|
||||
$messages = '';
|
||||
$data = '';
|
||||
|
||||
if( !isset($_SESSION['flash_messages']) ) return false;
|
||||
|
||||
if( $type == 'g' || $type == 'growl' ) {
|
||||
$this->displayGrowlMessages();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Print a certain type of message?
|
||||
if( in_array($type, $this->msgTypes) ) {
|
||||
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
|
||||
$messages .= $this->msgBefore . $msg . $this->msgAfter;
|
||||
}
|
||||
|
||||
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
|
||||
|
||||
// Clear the viewed messages
|
||||
$this->clear($type);
|
||||
|
||||
// Print ALL queued messages
|
||||
} elseif( $type == 'all' ) {
|
||||
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
|
||||
$messages = '';
|
||||
foreach( $msgArray as $msg ) {
|
||||
$messages .= $this->msgBefore . $msg . $this->msgAfter;
|
||||
}
|
||||
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
|
||||
}
|
||||
|
||||
// Clear ALL of the messages
|
||||
$this->clear();
|
||||
|
||||
// Invalid Message Type?
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print everything to the screen or return the data
|
||||
if( $print ) {
|
||||
echo $data;
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if there are any queued error messages
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @return bool true = There ARE error messages
|
||||
* false = There are NOT any error messages
|
||||
*
|
||||
*/
|
||||
public function hasErrors() {
|
||||
return empty($_SESSION['flash_messages']['error']) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if there are any ($type) messages queued
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of messages to check for
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function hasMessages($type=null) {
|
||||
if( !is_null($type) ) {
|
||||
if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
|
||||
} else {
|
||||
foreach( $this->msgTypes as $type ) {
|
||||
if( !empty($_SESSION['flash_messages']) ) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear messages from the session data
|
||||
*
|
||||
* @author Mike Everhart
|
||||
*
|
||||
* @param string $type The type of messages to clear
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function clear($type='all') {
|
||||
if( $type == 'all' ) {
|
||||
unset($_SESSION['flash_messages']);
|
||||
} else {
|
||||
unset($_SESSION['flash_messages'][$type]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function __toString() { return $this->hasMessages(); }
|
||||
|
||||
public function __destruct() {
|
||||
//$this->clear();
|
||||
}
|
||||
|
||||
|
||||
} // end class
|
||||
?>
|
||||
461
inc/3rdparty/config.php
vendored
Executable file
@ -0,0 +1,461 @@
|
||||
<?php
|
||||
/* Full-Text RSS config */
|
||||
|
||||
// ......IMPORTANT......................................
|
||||
// .....................................................
|
||||
// Please do not change this file (config.php) directly.
|
||||
// Save a copy as custom_config.php and make your
|
||||
// changes to that instead. It will automatically
|
||||
// override anything in config.php. Because config.php
|
||||
// always gets loaded anyway, you can simply specify
|
||||
// options you'd like to override in custom_config.php.
|
||||
// .....................................................
|
||||
|
||||
global $options;
|
||||
|
||||
// Create config object
|
||||
if (!isset($options)) $options = new stdClass();
|
||||
|
||||
// Enable service
|
||||
// ----------------------
|
||||
// Set this to false if you want to disable the service.
|
||||
// If set to false, no feed is produced and users will
|
||||
// be told that the service is disabled.
|
||||
$options->enabled = true;
|
||||
|
||||
// Debug mode
|
||||
// ----------------------
|
||||
// Enable or disable debugging. When enabled debugging works by passing
|
||||
// &debug to the makefulltextfeed.php querystring.
|
||||
// Valid values:
|
||||
// true or 'user' (default) - let user decide
|
||||
// 'admin' - debug works only for logged in admin users
|
||||
// false - disabled
|
||||
$options->debug = true;
|
||||
|
||||
// Default entries (without access key)
|
||||
// ----------------------
|
||||
// The number of feed items to process when no API key is supplied
|
||||
// and no &max=x value is supplied in the querystring.
|
||||
$options->default_entries = 5;
|
||||
|
||||
// Max entries (without access key)
|
||||
// ----------------------
|
||||
// The maximum number of feed items to process when no access key is supplied.
|
||||
// This limits the user-supplied &max=x value. For example, if the user
|
||||
// asks for 20 items to be processed (&max=20), if max_entries is set to
|
||||
// 10, only 10 will be processed.
|
||||
$options->max_entries = 10;
|
||||
|
||||
// Full content
|
||||
// ----------------------
|
||||
// By default Full-Text RSS includes the extracted content in the output.
|
||||
// You can exclude this from the output by passing '&content=0' in the querystring.
|
||||
//
|
||||
// Possible values...
|
||||
// Always include: true
|
||||
// Never include: false
|
||||
// Include unless user overrides (&content=0): 'user' (default)
|
||||
//
|
||||
// Note: currently this does not disable full content extraction. It simply omits it
|
||||
// from the output.
|
||||
$options->content = 'user';
|
||||
|
||||
// Excerpts
|
||||
// ----------------------
|
||||
// By default Full-Text RSS does not include excerpts in the output.
|
||||
// You can enable this by passing '&summary=1' in the querystring.
|
||||
// This will include a plain text excerpt from the extracted content.
|
||||
//
|
||||
// Possible values...
|
||||
// Always include: true (recommended for new users)
|
||||
// Never include: false
|
||||
// Don't include unless user overrides (&summary=1): 'user' (default)
|
||||
//
|
||||
// Important: if both content and excerpts are requested, the excerpt will be
|
||||
// placed in the description element and the full content inside content:encoded.
|
||||
// If excerpts are not requested, the full content will go inside the description element.
|
||||
//
|
||||
// Why are we not returning both excerpts and content by default?
|
||||
// Mainly for backward compatibility.
|
||||
// Excerpts should appear in the feed item's description element. Previous versions
|
||||
// of Full-Text RSS did not return excerpts, so the description element was always
|
||||
// used for the full content (as recommended by the RSS advisory). When returning both,
|
||||
// we need somewhere else to place the content (content:encoded).
|
||||
// Having both enabled should not create any problems for news readers, but it may create
|
||||
// problems for developers upgrading from one of our earlier versions who may now find
|
||||
// their applications are returning excerpts instead of the full content they were
|
||||
// expecting. To avoid such surprises for users who are upgrading Full-Text RSS,
|
||||
// excerpts must be explicitly requested in the querystring by default.
|
||||
//
|
||||
// Why not use a different element name for excerpts?
|
||||
// According to the RSS advisory:
|
||||
// "Publishers who employ summaries should store the summary in description and
|
||||
// the full content in content:encoded, ordering description first within the item.
|
||||
// On items with no summary, the full content should be stored in description."
|
||||
// See: http://www.rssboard.org/rss-profile#namespace-elements-content-encoded
|
||||
//
|
||||
// For more consistent element naming, we recommend new users set this option to true.
|
||||
// The full content can still be excluded via the querystring, but the element names
|
||||
// will not change: when $options->summary = true, the description element will always
|
||||
// be reserved for the excerpt and content:encoded always for full content.
|
||||
$options->summary = 'user';
|
||||
|
||||
// Rewrite relative URLs
|
||||
// ----------------------
|
||||
// With this enabled relative URLs found in the extracted content
|
||||
// block are automatically rewritten as absolute URLs.
|
||||
$options->rewrite_relative_urls = true;
|
||||
|
||||
// Exclude items if extraction fails
|
||||
// ---------------------------------
|
||||
// Excludes items from the resulting feed
|
||||
// if we cannot extract any content from the
|
||||
// item URL.
|
||||
// Possible values...
|
||||
// Enable: true
|
||||
// Disable: false (default)
|
||||
// User decides: 'user' (this option will appear on the form)
|
||||
$options->exclude_items_on_fail = 'user';
|
||||
|
||||
// Enable multi-page support
|
||||
// -------------------------
|
||||
// If enabled, we will try to follow next page links on multi-page articles.
|
||||
// Currently this only happens for sites where next_page_link has been defined
|
||||
// in a site config file.
|
||||
$options->multipage = true;
|
||||
|
||||
// Enable caching
|
||||
// ----------------------
|
||||
// Enable this if you'd like to cache results
|
||||
// for 10 minutes. Cache files are written to disk (in cache/ subfolders
|
||||
// - which must be writable).
|
||||
// Initially it's best to keep this disabled to make sure everything works
|
||||
// as expected. If you have APC enabled, please also see smart_cache in the
|
||||
// advanced section.
|
||||
$options->caching = false;
|
||||
|
||||
// Cache directory
|
||||
// ----------------------
|
||||
// Only used if caching is true
|
||||
$options->cache_dir = dirname(__FILE__).'/cache';
|
||||
|
||||
// Message to prepend (without access key)
|
||||
// ----------------------
|
||||
// HTML to insert at the beginning of each feed item when no access key is supplied.
|
||||
// Substitution tags:
|
||||
// {url} - Feed item URL
|
||||
// {effective-url} - Feed item URL after we've followed all redirects
|
||||
$options->message_to_prepend = '';
|
||||
|
||||
// Message to append (without access key)
|
||||
// ----------------------
|
||||
// HTML to insert at the end of each feed item when no access key is supplied.
|
||||
// Substitution tags:
|
||||
// {url} - Feed item URL
|
||||
// {effective-url} - Feed item URL after we've followed all redirects
|
||||
$options->message_to_append = '';
|
||||
|
||||
// Error message when content extraction fails (without access key)
|
||||
// ----------------------
|
||||
$options->error_message = '[unable to retrieve full-text content]';
|
||||
|
||||
// Keep enclosure in feed items
|
||||
// If enabled, we will try to preserve enclosures if present.
|
||||
// ----------------------
|
||||
$options->keep_enclosures = true;
|
||||
|
||||
// Detect language
|
||||
// ---------------
|
||||
// Should we try and find/guess the language of the article being processed?
|
||||
// Values will be placed inside the <dc:language> element inside each <item> element
|
||||
// Possible values:
|
||||
// * Ignore language: 0
|
||||
// * Use article/feed metadata (e.g. HTML lang attribute): 1 (default)
|
||||
// * As above, but guess if not present: 2
|
||||
// * Always guess: 3
|
||||
// * User decides: 'user' (value of 0-3 can be passed in querystring: e.g. &l=2)
|
||||
$options->detect_language = 1;
|
||||
|
||||
// Registration key
|
||||
// ---------------
|
||||
// The registration key is optional. It is not required to use Full-Text RSS,
|
||||
// and does not affect the normal operation of Full-Text RSS. It is currently
|
||||
// only used on admin pages which help you update site patterns with the
|
||||
// latest version offered by FiveFilters.org. For these admin-related
|
||||
// tasks to complete, we will require a valid registration key.
|
||||
// If you would like one, you can purchase the latest version of Full-Text RSS
|
||||
// at http://fivefilters.org/content-only/
|
||||
// Your registration key will automatically be sent in the confirmation email.
|
||||
// Once you have it, simply copy and paste it here.
|
||||
$options->registration_key = '';
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// RESTRICT ACCESS /////////////////////////////
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// Admin credentials
|
||||
// ----------------------
|
||||
// Certain pages/actions, e.g. updating site patterns with our online tool, will require admin credentials.
|
||||
// To use these pages, enter a password here and you'll be prompted for it when you try to access those pages.
|
||||
// If no password or username is set, pages requiring admin privelages will be inaccessible.
|
||||
// The default username is 'admin'.
|
||||
// If overriding with an environment variable, separate username and password with a colon, e.g.:
|
||||
// ftr_admin_credentials: admin:my-secret-password
|
||||
// Example: $options->admin_credentials = array('username'=>'admin', 'password'=>'my-secret-password');
|
||||
$options->admin_credentials = array('username'=>'admin', 'password'=>'');
|
||||
|
||||
// URLs to allow
|
||||
// ----------------------
|
||||
// List of URLs (or parts of a URL) which the service will accept.
|
||||
// If the list is empty, all URLs (except those specified in the blocked list below)
|
||||
// will be permitted.
|
||||
// Empty: array();
|
||||
// Non-empty example: array('example.com', 'anothersite.org');
|
||||
$options->allowed_urls = array();
|
||||
|
||||
// URLs to block
|
||||
// ----------------------
|
||||
// List of URLs (or parts of a URL) which the service will not accept.
|
||||
// Note: this list is ignored if allowed_urls is not empty
|
||||
$options->blocked_urls = array();
|
||||
|
||||
// Key holder(s) only?
|
||||
// ----------------------
|
||||
// Set this to true if you want to restrict access only to
|
||||
// those with a key (see below to specify key(s)).
|
||||
// If set to true, no feed is produced unless a valid
|
||||
// key is provided.
|
||||
$options->key_required = false;
|
||||
|
||||
// Favour item titles in feed
|
||||
// ----------------------
|
||||
// By default, when processing feeds, we assume item titles in the feed
|
||||
// have not been truncated. So after processing web pages, the extracted titles
|
||||
// are not used in the generated feed. If you prefer to have extracted titles in
|
||||
// the feed you can either set this to false, in which case we will always favour
|
||||
// extracted titles. Alternatively, if set to 'user' (default) we'll use the
|
||||
// extracted title if you pass '&use_extracted_title' in the querystring.
|
||||
// Possible values:
|
||||
// * Favour feed titles: true
|
||||
// * Favour extracted titles: false
|
||||
// * Favour feed titles with user override: 'user' (default)
|
||||
// Note: this has no effect when the input URL is to a web page - in these cases
|
||||
// we always use the extracted title in the generated feed.
|
||||
$options->favour_feed_titles = 'user';
|
||||
|
||||
// Access keys (password protected access)
|
||||
// ------------------------------------
|
||||
// NOTE: You do not need an API key from fivefilters.org to run your own
|
||||
// copy of the code. This is here if you'd like to restrict access to
|
||||
// _your_ copy.
|
||||
// Keys let you group users - those with a key and those without - and
|
||||
// restrict access to the service to those without a key.
|
||||
// If you want everyone to access the service in the same way, you can
|
||||
// leave the array below empty and ignore the access key options further down.
|
||||
// The options further down let you control how the service should behave
|
||||
// in each mode.
|
||||
// Note: Explicitly including the index number (1 and 2 in the examples below)
|
||||
// is highly recommended (when generating feeds, we encode the key and
|
||||
// refer to it by index number and hash).
|
||||
$options->api_keys = array();
|
||||
// Example:
|
||||
// $options->api_keys[1] = 'secret-key-1';
|
||||
// $options->api_keys[2] = 'secret-key-2';
|
||||
|
||||
// Default entries (with access key)
|
||||
// ----------------------
|
||||
// The number of feed items to process when a valid access key is supplied.
|
||||
$options->default_entries_with_key = 5;
|
||||
|
||||
// Max entries (with access key)
|
||||
// ----------------------
|
||||
// The maximum number of feed items to process when a valid access key is supplied.
|
||||
$options->max_entries_with_key = 10;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// ADVANCED OPTIONS ////////////////////////////
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// Enable XSS filter?
|
||||
// ----------------------
|
||||
// We have not enabled this by default because we assume the majority of
|
||||
// our users do not display the HTML retrieved by Full-Text RSS
|
||||
// in a web page without further processing. If you subscribe to our generated
|
||||
// feeds in your news reader application, it should, if it's good software, already
|
||||
// filter the resulting HTML for XSS attacks, making it redundant for
|
||||
// Full-Text RSS do the same. Similarly with frameworks/CMS which display
|
||||
// feed content - the content should be treated like any other user-submitted content.
|
||||
//
|
||||
// If you are writing an application yourself which is processing feeds generated by
|
||||
// Full-Text RSS, you can either filter the HTML yourself to remove potential XSS attacks
|
||||
// or enable this option. This might be useful if you are processing our generated
|
||||
// feeds with JavaScript on the client side - although there's client side xss
|
||||
// filtering available too, e.g. https://code.google.com/p/google-caja/wiki/JsHtmlSanitizer
|
||||
//
|
||||
// If enabled, we'll pass retrieved HTML content through htmLawed with
|
||||
// safe flag on and style attributes denied, see
|
||||
// http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/htmLawed_README.htm#s3.6
|
||||
// Note: if enabled this will also remove certain elements you may want to preserve, such as iframes.
|
||||
//
|
||||
// Valid values:
|
||||
// true - enabled, all content will be filtered
|
||||
// 'user' (default) - user must pass &xss in makefulltextfeed.php querystring to enable
|
||||
// false - disabled
|
||||
$options->xss_filter = 'user';
|
||||
|
||||
// Allowed parsers
|
||||
// ----------------------
|
||||
// Full-Text RSS attempts to use PHP's libxml extension to process HTML.
|
||||
// While fast, on some sites it may not always produce good results.
|
||||
// For these sites, you can specify an alternative HTML parser:
|
||||
// parser: html5lib
|
||||
// The html5lib parser is bundled with Full-Text RSS.
|
||||
// see http://code.google.com/p/html5lib/
|
||||
//
|
||||
// To disable HTML parsing with html5lib, you can remove it from this list.
|
||||
// By default we allow both: libxml and html5lib.
|
||||
$options->allowed_parsers = array('libxml', 'html5lib');
|
||||
//$options->allowed_parsers = array('libxml'); //disable html5lib - forcing libxml in all cases
|
||||
|
||||
// Enable Cross-Origin Resource Sharing (CORS)
|
||||
// ----------------------
|
||||
// If enabled we'll send the following HTTP header
|
||||
// Access-Control-Allow-Origin: *
|
||||
// see http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
|
||||
$options->cors = false;
|
||||
|
||||
// Use APC user cache?
|
||||
// ----------------------
|
||||
// If enabled we will store site config files (when requested
|
||||
// for the first time) in APC's user cache. Keys prefixed with 'sc.'
|
||||
// This improves performance by reducing disk access.
|
||||
// Note: this has no effect if APC is unavailable on your server.
|
||||
$options->apc = true;
|
||||
|
||||
// Smart cache (experimental)
|
||||
// ----------------------
|
||||
// With this option enabled we will not cache to disk immediately.
|
||||
// We will store the cache key in APC and if it's requested again
|
||||
// we will cache results to disk. Keys prefixed with 'cache.'
|
||||
// This improves performance by reducing disk access.
|
||||
// Note: this has no effect if APC is disabled or unavailable on your server,
|
||||
// or if you have caching disabled.
|
||||
$options->smart_cache = true;
|
||||
|
||||
// Fingerprints
|
||||
// ----------------------
|
||||
// key is fingerprint (fragment to find in HTML)
|
||||
// value is host name to use for site config lookup if fingerprint matches
|
||||
$options->fingerprints = array(
|
||||
// Posterous
|
||||
'<meta name="generator" content="Posterous"' => array('hostname'=>'fingerprint.posterous.com', 'head'=>true),
|
||||
// Blogger
|
||||
'<meta content=\'blogger\' name=\'generator\'' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
|
||||
'<meta name="generator" content="Blogger"' => array('hostname'=>'fingerprint.blogspot.com', 'head'=>true),
|
||||
// WordPress (hosted)
|
||||
// '<meta name="generator" content="WordPress.com"' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true),
|
||||
// WordPress (self-hosted and hosted)
|
||||
'<meta name="generator" content="WordPress' => array('hostname'=>'fingerprint.wordpress.com', 'head'=>true)
|
||||
);
|
||||
|
||||
// User Agent strings - mapping domain names
|
||||
// ----------------------
|
||||
// e.g. $options->user_agents = array('example.org' => 'PHP/5.2');
|
||||
$options->user_agents = array( 'lifehacker.com' => 'PHP/5.2',
|
||||
'gawker.com' => 'PHP/5.2',
|
||||
'deadspin.com' => 'PHP/5.2',
|
||||
'kotaku.com' => 'PHP/5.2',
|
||||
'jezebel.com' => 'PHP/5.2',
|
||||
'io9.com' => 'PHP/5.2',
|
||||
'jalopnik.com' => 'PHP/5.2',
|
||||
'gizmodo.com' => 'PHP/5.2',
|
||||
'.wikipedia.org' => 'Mozilla/5.2',
|
||||
'.fok.nl' => 'Googlebot/2.1',
|
||||
'getpocket.com' => 'PHP/5.2'
|
||||
);
|
||||
|
||||
// URL Rewriting
|
||||
// ----------------------
|
||||
// Currently allows simple string replace of URLs.
|
||||
// Useful for rewriting certain URLs to point to a single page
|
||||
// or HTML view. Although using the single_page_link site config
|
||||
// instruction is the preferred way to do this, sometimes, as
|
||||
// with Google Docs URLs, it's not possible.
|
||||
// Note: this might move to the site config file at some point.
|
||||
$options->rewrite_url = array(
|
||||
// Rewrite public Google Docs URLs to point to HTML view:
|
||||
// if a URL contains docs.google.com, replace /Doc? with /View?
|
||||
'docs.google.com' => array('/Doc?' => '/View?'),
|
||||
'tnr.com' => array('tnr.com/article/' => 'tnr.com/print/article/'),
|
||||
'.m.wikipedia.org' => array('.m.wikipedia.org' => '.wikipedia.org'),
|
||||
'm.vanityfair.com' => array('m.vanityfair.com' => 'www.vanityfair.com')
|
||||
);
|
||||
|
||||
// Content-Type exceptions
|
||||
// -----------------------
|
||||
// Here you can define different actions based
|
||||
// on the Content-Type header returned by server.
|
||||
// MIME type as key, action as value.
|
||||
// Valid actions:
|
||||
// * 'exclude' - exclude this item from the result
|
||||
// * 'link' - create HTML link to the item
|
||||
$options->content_type_exc = array(
|
||||
'application/pdf' => array('action'=>'link', 'name'=>'PDF'),
|
||||
'image' => array('action'=>'link', 'name'=>'Image'),
|
||||
'audio' => array('action'=>'link', 'name'=>'Audio'),
|
||||
'video' => array('action'=>'link', 'name'=>'Video')
|
||||
);
|
||||
|
||||
// Cache directory level
|
||||
// ----------------------
|
||||
// Spread cache files over different directories (only used if caching is enabled).
|
||||
// Used to prevent large number of files in one directory.
|
||||
// This corresponds to Zend_Cache's hashed_directory_level
|
||||
// see http://framework.zend.com/manual/en/zend.cache.backends.html
|
||||
// It's best not to change this if you're unsure.
|
||||
$options->cache_directory_level = 0;
|
||||
|
||||
// Cache cleanup
|
||||
// -------------
|
||||
// 0 = script will not clean cache (rename cachecleanup.php and use it for scheduled (e.g. cron) cache cleanup)
|
||||
// 1 = clean cache everytime the script runs (not recommended)
|
||||
// 100 = clean cache roughly once every 100 script runs
|
||||
// x = clean cache roughly once every x script runs
|
||||
// ...you get the idea :)
|
||||
$options->cache_cleanup = 100;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// DO NOT CHANGE ANYTHING BELOW THIS ///////////
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
if (!defined('_FF_FTR_VERSION')) define('_FF_FTR_VERSION', '3.2');
|
||||
|
||||
if (basename(__FILE__) == 'config.php') {
|
||||
if (file_exists(dirname(__FILE__).'/custom_config.php')) {
|
||||
require_once dirname(__FILE__).'/custom_config.php';
|
||||
}
|
||||
|
||||
// check for environment variables - often used on cloud platforms
|
||||
// environment variables should be prefixed with 'ftr_', e.g.
|
||||
// ftr_max_entries: 1
|
||||
// will set the max_entries value to 1.
|
||||
foreach ($options as $_key=>&$_val) {
|
||||
$_key = "ftr_$_key";
|
||||
if (($_env = getenv($_key)) !== false) {
|
||||
if (is_array($_val)) {
|
||||
if ($_key === 'ftr_admin_credentials') {
|
||||
$_val = array_combine(array('username', 'password'), array_map('trim', explode(':', $_env, 2)));
|
||||
if ($_val === false) $_val = array('username'=>'admin', 'password'=>'');
|
||||
}
|
||||
} elseif ($_env === 'true' || $_env === 'false') {
|
||||
$_val = ($_env === 'true');
|
||||
} elseif (is_numeric($_env)) {
|
||||
$_val = (int)$_env;
|
||||
} else { // string
|
||||
$_val = $_env;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($_key, $_val, $_env);
|
||||
}
|
||||
11
inc/3rdparty/htmlpurifier/HTMLPurifier.auto.php
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a stub include that automatically configures the include path.
|
||||
*/
|
||||
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
require_once 'HTMLPurifier/Bootstrap.php';
|
||||
require_once 'HTMLPurifier.autoload.php';
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
27
inc/3rdparty/htmlpurifier/HTMLPurifier.autoload.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Convenience file that registers autoload handler for HTML Purifier.
|
||||
* It also does some sanity checks.
|
||||
*/
|
||||
|
||||
if (function_exists('spl_autoload_register') && function_exists('spl_autoload_unregister')) {
|
||||
// We need unregister for our pre-registering functionality
|
||||
HTMLPurifier_Bootstrap::registerAutoload();
|
||||
if (function_exists('__autoload')) {
|
||||
// Be polite and ensure that userland autoload gets retained
|
||||
spl_autoload_register('__autoload');
|
||||
}
|
||||
} elseif (!function_exists('__autoload')) {
|
||||
function __autoload($class)
|
||||
{
|
||||
return HTMLPurifier_Bootstrap::autoload($class);
|
||||
}
|
||||
}
|
||||
|
||||
if (ini_get('zend.ze1_compatibility_mode')) {
|
||||
trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
4
inc/3rdparty/htmlpurifier/HTMLPurifier.composer.php
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
if (!defined('HTMLPURIFIER_PREFIX')) {
|
||||
define('HTMLPURIFIER_PREFIX', __DIR__);
|
||||
}
|
||||
25
inc/3rdparty/htmlpurifier/HTMLPurifier.func.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines a function wrapper for HTML Purifier for quick use.
|
||||
* @note ''HTMLPurifier()'' is NOT the same as ''new HTMLPurifier()''
|
||||
*/
|
||||
|
||||
/**
|
||||
* Purify HTML.
|
||||
* @param string $html String HTML to purify
|
||||
* @param mixed $config Configuration to use, can be any value accepted by
|
||||
* HTMLPurifier_Config::create()
|
||||
* @return string
|
||||
*/
|
||||
function HTMLPurifier($html, $config = null)
|
||||
{
|
||||
static $purifier = false;
|
||||
if (!$purifier) {
|
||||
$purifier = new HTMLPurifier();
|
||||
}
|
||||
return $purifier->purify($html, $config);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
229
inc/3rdparty/htmlpurifier/HTMLPurifier.includes.php
vendored
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file was auto-generated by generate-includes.php and includes all of
|
||||
* the core files required by HTML Purifier. Use this if performance is a
|
||||
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
|
||||
* FILE, changes will be overwritten the next time the script is run.
|
||||
*
|
||||
* @version 4.6.0
|
||||
*
|
||||
* @warning
|
||||
* You must *not* include any other HTML Purifier files before this file,
|
||||
* because 'require' not 'require_once' is used.
|
||||
*
|
||||
* @warning
|
||||
* This file requires that the include path contains the HTML Purifier
|
||||
* library directory; this is not auto-set.
|
||||
*/
|
||||
|
||||
require 'HTMLPurifier.php';
|
||||
require 'HTMLPurifier/Arborize.php';
|
||||
require 'HTMLPurifier/AttrCollections.php';
|
||||
require 'HTMLPurifier/AttrDef.php';
|
||||
require 'HTMLPurifier/AttrTransform.php';
|
||||
require 'HTMLPurifier/AttrTypes.php';
|
||||
require 'HTMLPurifier/AttrValidator.php';
|
||||
require 'HTMLPurifier/Bootstrap.php';
|
||||
require 'HTMLPurifier/Definition.php';
|
||||
require 'HTMLPurifier/CSSDefinition.php';
|
||||
require 'HTMLPurifier/ChildDef.php';
|
||||
require 'HTMLPurifier/Config.php';
|
||||
require 'HTMLPurifier/ConfigSchema.php';
|
||||
require 'HTMLPurifier/ContentSets.php';
|
||||
require 'HTMLPurifier/Context.php';
|
||||
require 'HTMLPurifier/DefinitionCache.php';
|
||||
require 'HTMLPurifier/DefinitionCacheFactory.php';
|
||||
require 'HTMLPurifier/Doctype.php';
|
||||
require 'HTMLPurifier/DoctypeRegistry.php';
|
||||
require 'HTMLPurifier/ElementDef.php';
|
||||
require 'HTMLPurifier/Encoder.php';
|
||||
require 'HTMLPurifier/EntityLookup.php';
|
||||
require 'HTMLPurifier/EntityParser.php';
|
||||
require 'HTMLPurifier/ErrorCollector.php';
|
||||
require 'HTMLPurifier/ErrorStruct.php';
|
||||
require 'HTMLPurifier/Exception.php';
|
||||
require 'HTMLPurifier/Filter.php';
|
||||
require 'HTMLPurifier/Generator.php';
|
||||
require 'HTMLPurifier/HTMLDefinition.php';
|
||||
require 'HTMLPurifier/HTMLModule.php';
|
||||
require 'HTMLPurifier/HTMLModuleManager.php';
|
||||
require 'HTMLPurifier/IDAccumulator.php';
|
||||
require 'HTMLPurifier/Injector.php';
|
||||
require 'HTMLPurifier/Language.php';
|
||||
require 'HTMLPurifier/LanguageFactory.php';
|
||||
require 'HTMLPurifier/Length.php';
|
||||
require 'HTMLPurifier/Lexer.php';
|
||||
require 'HTMLPurifier/Node.php';
|
||||
require 'HTMLPurifier/PercentEncoder.php';
|
||||
require 'HTMLPurifier/PropertyList.php';
|
||||
require 'HTMLPurifier/PropertyListIterator.php';
|
||||
require 'HTMLPurifier/Queue.php';
|
||||
require 'HTMLPurifier/Strategy.php';
|
||||
require 'HTMLPurifier/StringHash.php';
|
||||
require 'HTMLPurifier/StringHashParser.php';
|
||||
require 'HTMLPurifier/TagTransform.php';
|
||||
require 'HTMLPurifier/Token.php';
|
||||
require 'HTMLPurifier/TokenFactory.php';
|
||||
require 'HTMLPurifier/URI.php';
|
||||
require 'HTMLPurifier/URIDefinition.php';
|
||||
require 'HTMLPurifier/URIFilter.php';
|
||||
require 'HTMLPurifier/URIParser.php';
|
||||
require 'HTMLPurifier/URIScheme.php';
|
||||
require 'HTMLPurifier/URISchemeRegistry.php';
|
||||
require 'HTMLPurifier/UnitConverter.php';
|
||||
require 'HTMLPurifier/VarParser.php';
|
||||
require 'HTMLPurifier/VarParserException.php';
|
||||
require 'HTMLPurifier/Zipper.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS.php';
|
||||
require 'HTMLPurifier/AttrDef/Clone.php';
|
||||
require 'HTMLPurifier/AttrDef/Enum.php';
|
||||
require 'HTMLPurifier/AttrDef/Integer.php';
|
||||
require 'HTMLPurifier/AttrDef/Lang.php';
|
||||
require 'HTMLPurifier/AttrDef/Switch.php';
|
||||
require 'HTMLPurifier/AttrDef/Text.php';
|
||||
require 'HTMLPurifier/AttrDef/URI.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/AlphaValue.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Background.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Ident.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require 'HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Class.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
||||
require 'HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Email.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||
require 'HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||
require 'HTMLPurifier/AttrTransform/Background.php';
|
||||
require 'HTMLPurifier/AttrTransform/BdoDir.php';
|
||||
require 'HTMLPurifier/AttrTransform/BgColor.php';
|
||||
require 'HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||
require 'HTMLPurifier/AttrTransform/Border.php';
|
||||
require 'HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||
require 'HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||
require 'HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require 'HTMLPurifier/AttrTransform/Input.php';
|
||||
require 'HTMLPurifier/AttrTransform/Lang.php';
|
||||
require 'HTMLPurifier/AttrTransform/Length.php';
|
||||
require 'HTMLPurifier/AttrTransform/Name.php';
|
||||
require 'HTMLPurifier/AttrTransform/NameSync.php';
|
||||
require 'HTMLPurifier/AttrTransform/Nofollow.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeEmbed.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeObject.php';
|
||||
require 'HTMLPurifier/AttrTransform/SafeParam.php';
|
||||
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require 'HTMLPurifier/AttrTransform/TargetBlank.php';
|
||||
require 'HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require 'HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require 'HTMLPurifier/ChildDef/Custom.php';
|
||||
require 'HTMLPurifier/ChildDef/Empty.php';
|
||||
require 'HTMLPurifier/ChildDef/List.php';
|
||||
require 'HTMLPurifier/ChildDef/Required.php';
|
||||
require 'HTMLPurifier/ChildDef/Optional.php';
|
||||
require 'HTMLPurifier/ChildDef/StrictBlockquote.php';
|
||||
require 'HTMLPurifier/ChildDef/Table.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Decorator.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Null.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
|
||||
require 'HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
||||
require 'HTMLPurifier/HTMLModule/Bdo.php';
|
||||
require 'HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Edit.php';
|
||||
require 'HTMLPurifier/HTMLModule/Forms.php';
|
||||
require 'HTMLPurifier/HTMLModule/Hypertext.php';
|
||||
require 'HTMLPurifier/HTMLModule/Iframe.php';
|
||||
require 'HTMLPurifier/HTMLModule/Image.php';
|
||||
require 'HTMLPurifier/HTMLModule/Legacy.php';
|
||||
require 'HTMLPurifier/HTMLModule/List.php';
|
||||
require 'HTMLPurifier/HTMLModule/Name.php';
|
||||
require 'HTMLPurifier/HTMLModule/Nofollow.php';
|
||||
require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Object.php';
|
||||
require 'HTMLPurifier/HTMLModule/Presentation.php';
|
||||
require 'HTMLPurifier/HTMLModule/Proprietary.php';
|
||||
require 'HTMLPurifier/HTMLModule/Ruby.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeEmbed.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeObject.php';
|
||||
require 'HTMLPurifier/HTMLModule/SafeScripting.php';
|
||||
require 'HTMLPurifier/HTMLModule/Scripting.php';
|
||||
require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tables.php';
|
||||
require 'HTMLPurifier/HTMLModule/Target.php';
|
||||
require 'HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require 'HTMLPurifier/HTMLModule/Text.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require 'HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||
require 'HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||
require 'HTMLPurifier/Injector/AutoParagraph.php';
|
||||
require 'HTMLPurifier/Injector/DisplayLinkURI.php';
|
||||
require 'HTMLPurifier/Injector/Linkify.php';
|
||||
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
||||
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
||||
require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||
require 'HTMLPurifier/Injector/SafeObject.php';
|
||||
require 'HTMLPurifier/Lexer/DOMLex.php';
|
||||
require 'HTMLPurifier/Lexer/DirectLex.php';
|
||||
require 'HTMLPurifier/Node/Comment.php';
|
||||
require 'HTMLPurifier/Node/Element.php';
|
||||
require 'HTMLPurifier/Node/Text.php';
|
||||
require 'HTMLPurifier/Strategy/Composite.php';
|
||||
require 'HTMLPurifier/Strategy/Core.php';
|
||||
require 'HTMLPurifier/Strategy/FixNesting.php';
|
||||
require 'HTMLPurifier/Strategy/MakeWellFormed.php';
|
||||
require 'HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
require 'HTMLPurifier/Strategy/ValidateAttributes.php';
|
||||
require 'HTMLPurifier/TagTransform/Font.php';
|
||||
require 'HTMLPurifier/TagTransform/Simple.php';
|
||||
require 'HTMLPurifier/Token/Comment.php';
|
||||
require 'HTMLPurifier/Token/Tag.php';
|
||||
require 'HTMLPurifier/Token/Empty.php';
|
||||
require 'HTMLPurifier/Token/End.php';
|
||||
require 'HTMLPurifier/Token/Start.php';
|
||||
require 'HTMLPurifier/Token/Text.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableExternal.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||
require 'HTMLPurifier/URIFilter/DisableResources.php';
|
||||
require 'HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||
require 'HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||
require 'HTMLPurifier/URIFilter/Munge.php';
|
||||
require 'HTMLPurifier/URIFilter/SafeIframe.php';
|
||||
require 'HTMLPurifier/URIScheme/data.php';
|
||||
require 'HTMLPurifier/URIScheme/file.php';
|
||||
require 'HTMLPurifier/URIScheme/ftp.php';
|
||||
require 'HTMLPurifier/URIScheme/http.php';
|
||||
require 'HTMLPurifier/URIScheme/https.php';
|
||||
require 'HTMLPurifier/URIScheme/mailto.php';
|
||||
require 'HTMLPurifier/URIScheme/news.php';
|
||||
require 'HTMLPurifier/URIScheme/nntp.php';
|
||||
require 'HTMLPurifier/VarParser/Flexible.php';
|
||||
require 'HTMLPurifier/VarParser/Native.php';
|
||||
30
inc/3rdparty/htmlpurifier/HTMLPurifier.kses.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Emulation layer for code that used kses(), substituting in HTML Purifier.
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/HTMLPurifier.auto.php';
|
||||
|
||||
function kses($string, $allowed_html, $allowed_protocols = null)
|
||||
{
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$allowed_elements = array();
|
||||
$allowed_attributes = array();
|
||||
foreach ($allowed_html as $element => $attributes) {
|
||||
$allowed_elements[$element] = true;
|
||||
foreach ($attributes as $attribute => $x) {
|
||||
$allowed_attributes["$element.$attribute"] = true;
|
||||
}
|
||||
}
|
||||
$config->set('HTML.AllowedElements', $allowed_elements);
|
||||
$config->set('HTML.AllowedAttributes', $allowed_attributes);
|
||||
if ($allowed_protocols !== null) {
|
||||
$config->set('URI.AllowedSchemes', $allowed_protocols);
|
||||
}
|
||||
$purifier = new HTMLPurifier($config);
|
||||
return $purifier->purify($string);
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
11
inc/3rdparty/htmlpurifier/HTMLPurifier.path.php
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Convenience stub file that adds HTML Purifier's library file to the path
|
||||
* without any other side-effects.
|
||||
*/
|
||||
|
||||
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path() );
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
292
inc/3rdparty/htmlpurifier/HTMLPurifier.php
vendored
Normal file
@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
/*! @mainpage
|
||||
*
|
||||
* HTML Purifier is an HTML filter that will take an arbitrary snippet of
|
||||
* HTML and rigorously test, validate and filter it into a version that
|
||||
* is safe for output onto webpages. It achieves this by:
|
||||
*
|
||||
* -# Lexing (parsing into tokens) the document,
|
||||
* -# Executing various strategies on the tokens:
|
||||
* -# Removing all elements not in the whitelist,
|
||||
* -# Making the tokens well-formed,
|
||||
* -# Fixing the nesting of the nodes, and
|
||||
* -# Validating attributes of the nodes; and
|
||||
* -# Generating HTML from the purified tokens.
|
||||
*
|
||||
* However, most users will only need to interface with the HTMLPurifier
|
||||
* and HTMLPurifier_Config.
|
||||
*/
|
||||
|
||||
/*
|
||||
HTML Purifier 4.6.0 - Standards Compliant HTML Filtering
|
||||
Copyright (C) 2006-2008 Edward Z. Yang
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* Facade that coordinates HTML Purifier's subsystems in order to purify HTML.
|
||||
*
|
||||
* @note There are several points in which configuration can be specified
|
||||
* for HTML Purifier. The precedence of these (from lowest to
|
||||
* highest) is as follows:
|
||||
* -# Instance: new HTMLPurifier($config)
|
||||
* -# Invocation: purify($html, $config)
|
||||
* These configurations are entirely independent of each other and
|
||||
* are *not* merged (this behavior may change in the future).
|
||||
*
|
||||
* @todo We need an easier way to inject strategies using the configuration
|
||||
* object.
|
||||
*/
|
||||
class HTMLPurifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Version of HTML Purifier.
|
||||
* @type string
|
||||
*/
|
||||
public $version = '4.6.0';
|
||||
|
||||
/**
|
||||
* Constant with version of HTML Purifier.
|
||||
*/
|
||||
const VERSION = '4.6.0';
|
||||
|
||||
/**
|
||||
* Global configuration object.
|
||||
* @type HTMLPurifier_Config
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* Array of extra filter objects to run on HTML,
|
||||
* for backwards compatibility.
|
||||
* @type HTMLPurifier_Filter[]
|
||||
*/
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
* Single instance of HTML Purifier.
|
||||
* @type HTMLPurifier
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Strategy_Core
|
||||
*/
|
||||
protected $strategy;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Generator
|
||||
*/
|
||||
protected $generator;
|
||||
|
||||
/**
|
||||
* Resultant context of last run purification.
|
||||
* Is an array of contexts if the last called method was purifyArray().
|
||||
* @type HTMLPurifier_Context
|
||||
*/
|
||||
public $context;
|
||||
|
||||
/**
|
||||
* Initializes the purifier.
|
||||
*
|
||||
* @param HTMLPurifier_Config $config Optional HTMLPurifier_Config object
|
||||
* for all instances of the purifier, if omitted, a default
|
||||
* configuration is supplied (which can be overridden on a
|
||||
* per-use basis).
|
||||
* The parameter can also be any type that
|
||||
* HTMLPurifier_Config::create() supports.
|
||||
*/
|
||||
public function __construct($config = null)
|
||||
{
|
||||
$this->config = HTMLPurifier_Config::create($config);
|
||||
$this->strategy = new HTMLPurifier_Strategy_Core();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filter to process the output. First come first serve
|
||||
*
|
||||
* @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object
|
||||
*/
|
||||
public function addFilter($filter)
|
||||
{
|
||||
trigger_error(
|
||||
'HTMLPurifier->addFilter() is deprecated, use configuration directives' .
|
||||
' in the Filter namespace or Filter.Custom',
|
||||
E_USER_WARNING
|
||||
);
|
||||
$this->filters[] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an HTML snippet/document to be XSS-free and standards-compliant.
|
||||
*
|
||||
* @param string $html String of HTML to purify
|
||||
* @param HTMLPurifier_Config $config Config object for this operation,
|
||||
* if omitted, defaults to the config object specified during this
|
||||
* object's construction. The parameter can also be any type
|
||||
* that HTMLPurifier_Config::create() supports.
|
||||
*
|
||||
* @return string Purified HTML
|
||||
*/
|
||||
public function purify($html, $config = null)
|
||||
{
|
||||
// :TODO: make the config merge in, instead of replace
|
||||
$config = $config ? HTMLPurifier_Config::create($config) : $this->config;
|
||||
|
||||
// implementation is partially environment dependant, partially
|
||||
// configuration dependant
|
||||
$lexer = HTMLPurifier_Lexer::create($config);
|
||||
|
||||
$context = new HTMLPurifier_Context();
|
||||
|
||||
// setup HTML generator
|
||||
$this->generator = new HTMLPurifier_Generator($config, $context);
|
||||
$context->register('Generator', $this->generator);
|
||||
|
||||
// set up global context variables
|
||||
if ($config->get('Core.CollectErrors')) {
|
||||
// may get moved out if other facilities use it
|
||||
$language_factory = HTMLPurifier_LanguageFactory::instance();
|
||||
$language = $language_factory->create($config, $context);
|
||||
$context->register('Locale', $language);
|
||||
|
||||
$error_collector = new HTMLPurifier_ErrorCollector($context);
|
||||
$context->register('ErrorCollector', $error_collector);
|
||||
}
|
||||
|
||||
// setup id_accumulator context, necessary due to the fact that
|
||||
// AttrValidator can be called from many places
|
||||
$id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context);
|
||||
$context->register('IDAccumulator', $id_accumulator);
|
||||
|
||||
$html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context);
|
||||
|
||||
// setup filters
|
||||
$filter_flags = $config->getBatch('Filter');
|
||||
$custom_filters = $filter_flags['Custom'];
|
||||
unset($filter_flags['Custom']);
|
||||
$filters = array();
|
||||
foreach ($filter_flags as $filter => $flag) {
|
||||
if (!$flag) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($filter, '.') !== false) {
|
||||
continue;
|
||||
}
|
||||
$class = "HTMLPurifier_Filter_$filter";
|
||||
$filters[] = new $class;
|
||||
}
|
||||
foreach ($custom_filters as $filter) {
|
||||
// maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat
|
||||
$filters[] = $filter;
|
||||
}
|
||||
$filters = array_merge($filters, $this->filters);
|
||||
// maybe prepare(), but later
|
||||
|
||||
for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) {
|
||||
$html = $filters[$i]->preFilter($html, $config, $context);
|
||||
}
|
||||
|
||||
// purified HTML
|
||||
$html =
|
||||
$this->generator->generateFromTokens(
|
||||
// list of tokens
|
||||
$this->strategy->execute(
|
||||
// list of un-purified tokens
|
||||
$lexer->tokenizeHTML(
|
||||
// un-purified HTML
|
||||
$html,
|
||||
$config,
|
||||
$context
|
||||
),
|
||||
$config,
|
||||
$context
|
||||
)
|
||||
);
|
||||
|
||||
for ($i = $filter_size - 1; $i >= 0; $i--) {
|
||||
$html = $filters[$i]->postFilter($html, $config, $context);
|
||||
}
|
||||
|
||||
$html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context);
|
||||
$this->context =& $context;
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an array of HTML snippets
|
||||
*
|
||||
* @param string[] $array_of_html Array of html snippets
|
||||
* @param HTMLPurifier_Config $config Optional config object for this operation.
|
||||
* See HTMLPurifier::purify() for more details.
|
||||
*
|
||||
* @return string[] Array of purified HTML
|
||||
*/
|
||||
public function purifyArray($array_of_html, $config = null)
|
||||
{
|
||||
$context_array = array();
|
||||
foreach ($array_of_html as $key => $html) {
|
||||
$array_of_html[$key] = $this->purify($html, $config);
|
||||
$context_array[$key] = $this->context;
|
||||
}
|
||||
$this->context = $context_array;
|
||||
return $array_of_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
*
|
||||
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
|
||||
* HTMLPurifier instance to overload singleton with,
|
||||
* or HTMLPurifier_Config instance to configure the
|
||||
* generated version with.
|
||||
*
|
||||
* @return HTMLPurifier
|
||||
*/
|
||||
public static function instance($prototype = null)
|
||||
{
|
||||
if (!self::$instance || $prototype) {
|
||||
if ($prototype instanceof HTMLPurifier) {
|
||||
self::$instance = $prototype;
|
||||
} elseif ($prototype) {
|
||||
self::$instance = new HTMLPurifier($prototype);
|
||||
} else {
|
||||
self::$instance = new HTMLPurifier();
|
||||
}
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton for enforcing just one HTML Purifier in your system
|
||||
*
|
||||
* @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype
|
||||
* HTMLPurifier instance to overload singleton with,
|
||||
* or HTMLPurifier_Config instance to configure the
|
||||
* generated version with.
|
||||
*
|
||||
* @return HTMLPurifier
|
||||
* @note Backwards compatibility, see instance()
|
||||
*/
|
||||
public static function getInstance($prototype = null)
|
||||
{
|
||||
return HTMLPurifier::instance($prototype);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
223
inc/3rdparty/htmlpurifier/HTMLPurifier.safe-includes.php
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file was auto-generated by generate-includes.php and includes all of
|
||||
* the core files required by HTML Purifier. This is a convenience stub that
|
||||
* includes all files using dirname(__FILE__) and require_once. PLEASE DO NOT
|
||||
* EDIT THIS FILE, changes will be overwritten the next time the script is run.
|
||||
*
|
||||
* Changes to include_path are not necessary.
|
||||
*/
|
||||
|
||||
$__dir = dirname(__FILE__);
|
||||
|
||||
require_once $__dir . '/HTMLPurifier.php';
|
||||
require_once $__dir . '/HTMLPurifier/Arborize.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrCollections.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTypes.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrValidator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Bootstrap.php';
|
||||
require_once $__dir . '/HTMLPurifier/Definition.php';
|
||||
require_once $__dir . '/HTMLPurifier/CSSDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Config.php';
|
||||
require_once $__dir . '/HTMLPurifier/ConfigSchema.php';
|
||||
require_once $__dir . '/HTMLPurifier/ContentSets.php';
|
||||
require_once $__dir . '/HTMLPurifier/Context.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCacheFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/Doctype.php';
|
||||
require_once $__dir . '/HTMLPurifier/DoctypeRegistry.php';
|
||||
require_once $__dir . '/HTMLPurifier/ElementDef.php';
|
||||
require_once $__dir . '/HTMLPurifier/Encoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityLookup.php';
|
||||
require_once $__dir . '/HTMLPurifier/EntityParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorCollector.php';
|
||||
require_once $__dir . '/HTMLPurifier/ErrorStruct.php';
|
||||
require_once $__dir . '/HTMLPurifier/Exception.php';
|
||||
require_once $__dir . '/HTMLPurifier/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/Generator.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModuleManager.php';
|
||||
require_once $__dir . '/HTMLPurifier/IDAccumulator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector.php';
|
||||
require_once $__dir . '/HTMLPurifier/Language.php';
|
||||
require_once $__dir . '/HTMLPurifier/LanguageFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node.php';
|
||||
require_once $__dir . '/HTMLPurifier/PercentEncoder.php';
|
||||
require_once $__dir . '/HTMLPurifier/PropertyList.php';
|
||||
require_once $__dir . '/HTMLPurifier/PropertyListIterator.php';
|
||||
require_once $__dir . '/HTMLPurifier/Queue.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHash.php';
|
||||
require_once $__dir . '/HTMLPurifier/StringHashParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token.php';
|
||||
require_once $__dir . '/HTMLPurifier/TokenFactory.php';
|
||||
require_once $__dir . '/HTMLPurifier/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIDefinition.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme.php';
|
||||
require_once $__dir . '/HTMLPurifier/URISchemeRegistry.php';
|
||||
require_once $__dir . '/HTMLPurifier/UnitConverter.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParserException.php';
|
||||
require_once $__dir . '/HTMLPurifier/Zipper.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Clone.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Enum.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Integer.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Lang.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Switch.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Number.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/AlphaValue.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Background.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ident.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/LinkTypes.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/MultiLength.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Host.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv4.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/IPv6.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Background.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BdoDir.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BgColor.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/BoolToCSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Border.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/EnumToCSS.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ImgSpace.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Input.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Lang.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Length.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/NameSync.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Nofollow.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeEmbed.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Custom.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Empty.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/List.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Required.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Optional.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/StrictBlockquote.php';
|
||||
require_once $__dir . '/HTMLPurifier/ChildDef/Table.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Null.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Serializer.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php';
|
||||
require_once $__dir . '/HTMLPurifier/DefinitionCache/Decorator/Memory.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Bdo.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/CommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Edit.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Forms.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Hypertext.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Iframe.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/List.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Nofollow.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Object.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Presentation.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Proprietary.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Ruby.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeEmbed.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeObject.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/SafeScripting.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Scripting.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetBlank.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/XMLCommonAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Name.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Proprietary.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Strict.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/Transitional.php';
|
||||
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy/XHTML.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Comment.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Element.php';
|
||||
require_once $__dir . '/HTMLPurifier/Node/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Composite.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/Core.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/FixNesting.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/MakeWellFormed.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/RemoveForeignElements.php';
|
||||
require_once $__dir . '/HTMLPurifier/Strategy/ValidateAttributes.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform/Font.php';
|
||||
require_once $__dir . '/HTMLPurifier/TagTransform/Simple.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Comment.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Tag.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Empty.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/End.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Start.php';
|
||||
require_once $__dir . '/HTMLPurifier/Token/Text.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternal.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableExternalResources.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/DisableResources.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/HostBlacklist.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/MakeAbsolute.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/Munge.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIFilter/SafeIframe.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/data.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/file.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/ftp.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/http.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/https.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/mailto.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/news.php';
|
||||
require_once $__dir . '/HTMLPurifier/URIScheme/nntp.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Flexible.php';
|
||||
require_once $__dir . '/HTMLPurifier/VarParser/Native.php';
|
||||
71
inc/3rdparty/htmlpurifier/HTMLPurifier/Arborize.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node,
|
||||
* and back again.
|
||||
*
|
||||
* @note This transformation is not an equivalence. We mutate the input
|
||||
* token stream to make it so; see all [MUT] markers in code.
|
||||
*/
|
||||
class HTMLPurifier_Arborize
|
||||
{
|
||||
public static function arborize($tokens, $config, $context) {
|
||||
$definition = $config->getHTMLDefinition();
|
||||
$parent = new HTMLPurifier_Token_Start($definition->info_parent);
|
||||
$stack = array($parent->toNode());
|
||||
foreach ($tokens as $token) {
|
||||
$token->skip = null; // [MUT]
|
||||
$token->carryover = null; // [MUT]
|
||||
if ($token instanceof HTMLPurifier_Token_End) {
|
||||
$token->start = null; // [MUT]
|
||||
$r = array_pop($stack);
|
||||
assert($r->name === $token->name);
|
||||
assert(empty($token->attr));
|
||||
$r->endCol = $token->col;
|
||||
$r->endLine = $token->line;
|
||||
$r->endArmor = $token->armor;
|
||||
continue;
|
||||
}
|
||||
$node = $token->toNode();
|
||||
$stack[count($stack)-1]->children[] = $node;
|
||||
if ($token instanceof HTMLPurifier_Token_Start) {
|
||||
$stack[] = $node;
|
||||
}
|
||||
}
|
||||
assert(count($stack) == 1);
|
||||
return $stack[0];
|
||||
}
|
||||
|
||||
public static function flatten($node, $config, $context) {
|
||||
$level = 0;
|
||||
$nodes = array($level => new HTMLPurifier_Queue(array($node)));
|
||||
$closingTokens = array();
|
||||
$tokens = array();
|
||||
do {
|
||||
while (!$nodes[$level]->isEmpty()) {
|
||||
$node = $nodes[$level]->shift(); // FIFO
|
||||
list($start, $end) = $node->toTokenPair();
|
||||
if ($level > 0) {
|
||||
$tokens[] = $start;
|
||||
}
|
||||
if ($end !== NULL) {
|
||||
$closingTokens[$level][] = $end;
|
||||
}
|
||||
if ($node instanceof HTMLPurifier_Node_Element) {
|
||||
$level++;
|
||||
$nodes[$level] = new HTMLPurifier_Queue();
|
||||
foreach ($node->children as $childNode) {
|
||||
$nodes[$level]->push($childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
$level--;
|
||||
if ($level && isset($closingTokens[$level])) {
|
||||
while ($token = array_pop($closingTokens[$level])) {
|
||||
$tokens[] = $token;
|
||||
}
|
||||
}
|
||||
} while ($level > 0);
|
||||
return $tokens;
|
||||
}
|
||||
}
|
||||
143
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrCollections.php
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Defines common attribute collections that modules reference
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrCollections
|
||||
{
|
||||
|
||||
/**
|
||||
* Associative array of attribute collections, indexed by name.
|
||||
* @type array
|
||||
*/
|
||||
public $info = array();
|
||||
|
||||
/**
|
||||
* Performs all expansions on internal data for use by other inclusions
|
||||
* It also collects all attribute collection extensions from
|
||||
* modules
|
||||
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
|
||||
* @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members
|
||||
*/
|
||||
public function __construct($attr_types, $modules)
|
||||
{
|
||||
// load extensions from the modules
|
||||
foreach ($modules as $module) {
|
||||
foreach ($module->attr_collections as $coll_i => $coll) {
|
||||
if (!isset($this->info[$coll_i])) {
|
||||
$this->info[$coll_i] = array();
|
||||
}
|
||||
foreach ($coll as $attr_i => $attr) {
|
||||
if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) {
|
||||
// merge in includes
|
||||
$this->info[$coll_i][$attr_i] = array_merge(
|
||||
$this->info[$coll_i][$attr_i],
|
||||
$attr
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$this->info[$coll_i][$attr_i] = $attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// perform internal expansions and inclusions
|
||||
foreach ($this->info as $name => $attr) {
|
||||
// merge attribute collections that include others
|
||||
$this->performInclusions($this->info[$name]);
|
||||
// replace string identifiers with actual attribute objects
|
||||
$this->expandIdentifiers($this->info[$name], $attr_types);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a reference to an attribute associative array and performs
|
||||
* all inclusions specified by the zero index.
|
||||
* @param array &$attr Reference to attribute array
|
||||
*/
|
||||
public function performInclusions(&$attr)
|
||||
{
|
||||
if (!isset($attr[0])) {
|
||||
return;
|
||||
}
|
||||
$merge = $attr[0];
|
||||
$seen = array(); // recursion guard
|
||||
// loop through all the inclusions
|
||||
for ($i = 0; isset($merge[$i]); $i++) {
|
||||
if (isset($seen[$merge[$i]])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$merge[$i]] = true;
|
||||
// foreach attribute of the inclusion, copy it over
|
||||
if (!isset($this->info[$merge[$i]])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($this->info[$merge[$i]] as $key => $value) {
|
||||
if (isset($attr[$key])) {
|
||||
continue;
|
||||
} // also catches more inclusions
|
||||
$attr[$key] = $value;
|
||||
}
|
||||
if (isset($this->info[$merge[$i]][0])) {
|
||||
// recursion
|
||||
$merge = array_merge($merge, $this->info[$merge[$i]][0]);
|
||||
}
|
||||
}
|
||||
unset($attr[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expands all string identifiers in an attribute array by replacing
|
||||
* them with the appropriate values inside HTMLPurifier_AttrTypes
|
||||
* @param array &$attr Reference to attribute array
|
||||
* @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance
|
||||
*/
|
||||
public function expandIdentifiers(&$attr, $attr_types)
|
||||
{
|
||||
// because foreach will process new elements we add, make sure we
|
||||
// skip duplicates
|
||||
$processed = array();
|
||||
|
||||
foreach ($attr as $def_i => $def) {
|
||||
// skip inclusions
|
||||
if ($def_i === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($processed[$def_i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// determine whether or not attribute is required
|
||||
if ($required = (strpos($def_i, '*') !== false)) {
|
||||
// rename the definition
|
||||
unset($attr[$def_i]);
|
||||
$def_i = trim($def_i, '*');
|
||||
$attr[$def_i] = $def;
|
||||
}
|
||||
|
||||
$processed[$def_i] = true;
|
||||
|
||||
// if we've already got a literal object, move on
|
||||
if (is_object($def)) {
|
||||
// preserve previous required
|
||||
$attr[$def_i]->required = ($required || $attr[$def_i]->required);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($def === false) {
|
||||
unset($attr[$def_i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($t = $attr_types->get($def)) {
|
||||
$attr[$def_i] = $t;
|
||||
$attr[$def_i]->required = $required;
|
||||
} else {
|
||||
unset($attr[$def_i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
138
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef.php
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for all validating attribute definitions.
|
||||
*
|
||||
* This family of classes forms the core for not only HTML attribute validation,
|
||||
* but also any sort of string that needs to be validated or cleaned (which
|
||||
* means CSS properties and composite definitions are defined here too).
|
||||
* Besides defining (through code) what precisely makes the string valid,
|
||||
* subclasses are also responsible for cleaning the code if possible.
|
||||
*/
|
||||
|
||||
abstract class HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is minimized.
|
||||
* Has no meaning in other contexts.
|
||||
* @type bool
|
||||
*/
|
||||
public $minimized = false;
|
||||
|
||||
/**
|
||||
* Tells us whether or not an HTML attribute is required.
|
||||
* Has no meaning in other contexts
|
||||
* @type bool
|
||||
*/
|
||||
public $required = false;
|
||||
|
||||
/**
|
||||
* Validates and cleans passed string according to a definition.
|
||||
*
|
||||
* @param string $string String to be validated and cleaned.
|
||||
* @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object.
|
||||
* @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object.
|
||||
*/
|
||||
abstract public function validate($string, $config, $context);
|
||||
|
||||
/**
|
||||
* Convenience method that parses a string as if it were CDATA.
|
||||
*
|
||||
* This method process a string in the manner specified at
|
||||
* <http://www.w3.org/TR/html4/types.html#h-6.2> by removing
|
||||
* leading and trailing whitespace, ignoring line feeds, and replacing
|
||||
* carriage returns and tabs with spaces. While most useful for HTML
|
||||
* attributes specified as CDATA, it can also be applied to most CSS
|
||||
* values.
|
||||
*
|
||||
* @note This method is not entirely standards compliant, as trim() removes
|
||||
* more types of whitespace than specified in the spec. In practice,
|
||||
* this is rarely a problem, as those extra characters usually have
|
||||
* already been removed by HTMLPurifier_Encoder.
|
||||
*
|
||||
* @warning This processing is inconsistent with XML's whitespace handling
|
||||
* as specified by section 3.3.3 and referenced XHTML 1.0 section
|
||||
* 4.7. However, note that we are NOT necessarily
|
||||
* parsing XML, thus, this behavior may still be correct. We
|
||||
* assume that newlines have been normalized.
|
||||
*/
|
||||
public function parseCDATA($string)
|
||||
{
|
||||
$string = trim($string);
|
||||
$string = str_replace(array("\n", "\t", "\r"), ' ', $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating this class from a string.
|
||||
* @param string $string String construction info
|
||||
* @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
// default implementation, return a flyweight of this object.
|
||||
// If $string has an effect on the returned object (i.e. you
|
||||
// need to overload this method), it is best
|
||||
// to clone or instantiate new copies. (Instantiation is safer.)
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work
|
||||
* properly. THIS IS A HACK!
|
||||
* @param string $string a CSS colour definition
|
||||
* @return string
|
||||
*/
|
||||
protected function mungeRgb($string)
|
||||
{
|
||||
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a possibly escaped CSS string and returns the "pure"
|
||||
* version of it.
|
||||
*/
|
||||
protected function expandCSSEscape($string)
|
||||
{
|
||||
// flexibly parse it
|
||||
$ret = '';
|
||||
for ($i = 0, $c = strlen($string); $i < $c; $i++) {
|
||||
if ($string[$i] === '\\') {
|
||||
$i++;
|
||||
if ($i >= $c) {
|
||||
$ret .= '\\';
|
||||
break;
|
||||
}
|
||||
if (ctype_xdigit($string[$i])) {
|
||||
$code = $string[$i];
|
||||
for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) {
|
||||
if (!ctype_xdigit($string[$i])) {
|
||||
break;
|
||||
}
|
||||
$code .= $string[$i];
|
||||
}
|
||||
// We have to be extremely careful when adding
|
||||
// new characters, to make sure we're not breaking
|
||||
// the encoding.
|
||||
$char = HTMLPurifier_Encoder::unichr(hexdec($code));
|
||||
if (HTMLPurifier_Encoder::cleanUTF8($char) === '') {
|
||||
continue;
|
||||
}
|
||||
$ret .= $char;
|
||||
if ($i < $c && trim($string[$i]) !== '') {
|
||||
$i--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($string[$i] === "\n") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$ret .= $string[$i];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
106
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute style, otherwise known as CSS.
|
||||
* @note We don't implement the whole CSS specification, so it might be
|
||||
* difficult to reuse this component in the context of validating
|
||||
* actual stylesheet declarations.
|
||||
* @note If we were really serious about validating the CSS, we would
|
||||
* tokenize the styles and then parse the tokens. Obviously, we
|
||||
* are not doing that. Doing that could seriously harm performance,
|
||||
* but would make these components a lot more viable for a CSS
|
||||
* filtering solution.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $css
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($css, $config, $context)
|
||||
{
|
||||
$css = $this->parseCDATA($css);
|
||||
|
||||
$definition = $config->getCSSDefinition();
|
||||
|
||||
// we're going to break the spec and explode by semicolons.
|
||||
// This is because semicolon rarely appears in escaped form
|
||||
// Doing this is generally flaky but fast
|
||||
// IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI
|
||||
// for details
|
||||
|
||||
$declarations = explode(';', $css);
|
||||
$propvalues = array();
|
||||
|
||||
/**
|
||||
* Name of the current CSS property being validated.
|
||||
*/
|
||||
$property = false;
|
||||
$context->register('CurrentCSSProperty', $property);
|
||||
|
||||
foreach ($declarations as $declaration) {
|
||||
if (!$declaration) {
|
||||
continue;
|
||||
}
|
||||
if (!strpos($declaration, ':')) {
|
||||
continue;
|
||||
}
|
||||
list($property, $value) = explode(':', $declaration, 2);
|
||||
$property = trim($property);
|
||||
$value = trim($value);
|
||||
$ok = false;
|
||||
do {
|
||||
if (isset($definition->info[$property])) {
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
if (ctype_lower($property)) {
|
||||
break;
|
||||
}
|
||||
$property = strtolower($property);
|
||||
if (isset($definition->info[$property])) {
|
||||
$ok = true;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
// inefficient call, since the validator will do this again
|
||||
if (strtolower(trim($value)) !== 'inherit') {
|
||||
// inherit works for everything (but only on the base property)
|
||||
$result = $definition->info[$property]->validate(
|
||||
$value,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
} else {
|
||||
$result = 'inherit';
|
||||
}
|
||||
if ($result === false) {
|
||||
continue;
|
||||
}
|
||||
$propvalues[$property] = $result;
|
||||
}
|
||||
|
||||
$context->destroy('CurrentCSSProperty');
|
||||
|
||||
// procedure does not write the new CSS simultaneously, so it's
|
||||
// slightly inefficient, but it's the only way of getting rid of
|
||||
// duplicates. Perhaps config to optimize it, but not now.
|
||||
|
||||
$new_declarations = '';
|
||||
foreach ($propvalues as $prop => $value) {
|
||||
$new_declarations .= "$prop:$value;";
|
||||
}
|
||||
|
||||
return $new_declarations ? $new_declarations : false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
34
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/AlphaValue.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(false); // opacity is non-negative, but we will clamp it
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return string
|
||||
*/
|
||||
public function validate($number, $config, $context)
|
||||
{
|
||||
$result = parent::validate($number, $config, $context);
|
||||
if ($result === false) {
|
||||
return $result;
|
||||
}
|
||||
$float = (float)$result;
|
||||
if ($float < 0.0) {
|
||||
$result = '0';
|
||||
}
|
||||
if ($float > 1.0) {
|
||||
$result = '1';
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
111
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Background.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property background.
|
||||
* @warning Does not support url tokens that have internal spaces.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of component validators.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['background-color'] = $def->info['background-color'];
|
||||
$this->info['background-image'] = $def->info['background-image'];
|
||||
$this->info['background-repeat'] = $def->info['background-repeat'];
|
||||
$this->info['background-attachment'] = $def->info['background-attachment'];
|
||||
$this->info['background-position'] = $def->info['background-position'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// munge rgb() decl if necessary
|
||||
$string = $this->mungeRgb($string);
|
||||
|
||||
// assumes URI doesn't have spaces in it
|
||||
$bits = explode(' ', $string); // bits to process
|
||||
|
||||
$caught = array();
|
||||
$caught['color'] = false;
|
||||
$caught['image'] = false;
|
||||
$caught['repeat'] = false;
|
||||
$caught['attachment'] = false;
|
||||
$caught['position'] = false;
|
||||
|
||||
$i = 0; // number of catches
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
foreach ($caught as $key => $status) {
|
||||
if ($key != 'position') {
|
||||
if ($status !== false) {
|
||||
continue;
|
||||
}
|
||||
$r = $this->info['background-' . $key]->validate($bit, $config, $context);
|
||||
} else {
|
||||
$r = $bit;
|
||||
}
|
||||
if ($r === false) {
|
||||
continue;
|
||||
}
|
||||
if ($key == 'position') {
|
||||
if ($caught[$key] === false) {
|
||||
$caught[$key] = '';
|
||||
}
|
||||
$caught[$key] .= $r . ' ';
|
||||
} else {
|
||||
$caught[$key] = $r;
|
||||
}
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
}
|
||||
if ($caught['position'] !== false) {
|
||||
$caught['position'] = $this->info['background-position']->
|
||||
validate($caught['position'], $config, $context);
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
foreach ($caught as $value) {
|
||||
if ($value === false) {
|
||||
continue;
|
||||
}
|
||||
$ret[] = $value;
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
157
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
/* W3C says:
|
||||
[ // adjective and number must be in correct order, even if
|
||||
// you could switch them without introducing ambiguity.
|
||||
// some browsers support that syntax
|
||||
[
|
||||
<percentage> | <length> | left | center | right
|
||||
]
|
||||
[
|
||||
<percentage> | <length> | top | center | bottom
|
||||
]?
|
||||
] |
|
||||
[ // this signifies that the vertical and horizontal adjectives
|
||||
// can be arbitrarily ordered, however, there can only be two,
|
||||
// one of each, or none at all
|
||||
[
|
||||
left | center | right
|
||||
] ||
|
||||
[
|
||||
top | center | bottom
|
||||
]
|
||||
]
|
||||
top, left = 0%
|
||||
center, (none) = 50%
|
||||
bottom, right = 100%
|
||||
*/
|
||||
|
||||
/* QuirksMode says:
|
||||
keyword + length/percentage must be ordered correctly, as per W3C
|
||||
|
||||
Internet Explorer and Opera, however, support arbitrary ordering. We
|
||||
should fix it up.
|
||||
|
||||
Minor issue though, not strictly necessary.
|
||||
*/
|
||||
|
||||
// control freaks may appreciate the ability to convert these to
|
||||
// percentages or something, but it's not necessary
|
||||
|
||||
/**
|
||||
* Validates the value of background-position.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_CSS_Length
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_CSS_Percentage
|
||||
*/
|
||||
protected $percentage;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
||||
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
$bits = explode(' ', $string);
|
||||
|
||||
$keywords = array();
|
||||
$keywords['h'] = false; // left, right
|
||||
$keywords['v'] = false; // top, bottom
|
||||
$keywords['ch'] = false; // center (first word)
|
||||
$keywords['cv'] = false; // center (second word)
|
||||
$measures = array();
|
||||
|
||||
$i = 0;
|
||||
|
||||
$lookup = array(
|
||||
'top' => 'v',
|
||||
'bottom' => 'v',
|
||||
'left' => 'h',
|
||||
'right' => 'h',
|
||||
'center' => 'c'
|
||||
);
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// test for keyword
|
||||
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
|
||||
if (isset($lookup[$lbit])) {
|
||||
$status = $lookup[$lbit];
|
||||
if ($status == 'c') {
|
||||
if ($i == 0) {
|
||||
$status = 'ch';
|
||||
} else {
|
||||
$status = 'cv';
|
||||
}
|
||||
}
|
||||
$keywords[$status] = $lbit;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// test for length
|
||||
$r = $this->length->validate($bit, $config, $context);
|
||||
if ($r !== false) {
|
||||
$measures[] = $r;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// test for percentage
|
||||
$r = $this->percentage->validate($bit, $config, $context);
|
||||
if ($r !== false) {
|
||||
$measures[] = $r;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
} // no valid values were caught
|
||||
|
||||
$ret = array();
|
||||
|
||||
// first keyword
|
||||
if ($keywords['h']) {
|
||||
$ret[] = $keywords['h'];
|
||||
} elseif ($keywords['ch']) {
|
||||
$ret[] = $keywords['ch'];
|
||||
$keywords['cv'] = false; // prevent re-use: center = center center
|
||||
} elseif (count($measures)) {
|
||||
$ret[] = array_shift($measures);
|
||||
}
|
||||
|
||||
if ($keywords['v']) {
|
||||
$ret[] = $keywords['v'];
|
||||
} elseif ($keywords['cv']) {
|
||||
$ret[] = $keywords['cv'];
|
||||
} elseif (count($measures)) {
|
||||
$ret[] = array_shift($measures);
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
56
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Border.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the border property as defined by CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of properties this property is shorthand for.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
*/
|
||||
protected $info = array();
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['border-width'] = $def->info['border-width'];
|
||||
$this->info['border-style'] = $def->info['border-style'];
|
||||
$this->info['border-top-color'] = $def->info['border-top-color'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
$string = $this->mungeRgb($string);
|
||||
$bits = explode(' ', $string);
|
||||
$done = array(); // segments we've finished
|
||||
$ret = ''; // return value
|
||||
foreach ($bits as $bit) {
|
||||
foreach ($this->info as $propname => $validator) {
|
||||
if (isset($done[$propname])) {
|
||||
continue;
|
||||
}
|
||||
$r = $validator->validate($bit, $config, $context);
|
||||
if ($r !== false) {
|
||||
$ret .= $r . ' ';
|
||||
$done[$propname] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rtrim($ret);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
105
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Color.php
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates Color as defined by CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $color
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($color, $config, $context)
|
||||
{
|
||||
static $colors = null;
|
||||
if ($colors === null) {
|
||||
$colors = $config->get('Core.ColorKeywords');
|
||||
}
|
||||
|
||||
$color = trim($color);
|
||||
if ($color === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lower = strtolower($color);
|
||||
if (isset($colors[$lower])) {
|
||||
return $colors[$lower];
|
||||
}
|
||||
|
||||
if (strpos($color, 'rgb(') !== false) {
|
||||
// rgb literal handling
|
||||
$length = strlen($color);
|
||||
if (strpos($color, ')') !== $length - 1) {
|
||||
return false;
|
||||
}
|
||||
$triad = substr($color, 4, $length - 4 - 1);
|
||||
$parts = explode(',', $triad);
|
||||
if (count($parts) !== 3) {
|
||||
return false;
|
||||
}
|
||||
$type = false; // to ensure that they're all the same type
|
||||
$new_parts = array();
|
||||
foreach ($parts as $part) {
|
||||
$part = trim($part);
|
||||
if ($part === '') {
|
||||
return false;
|
||||
}
|
||||
$length = strlen($part);
|
||||
if ($part[$length - 1] === '%') {
|
||||
// handle percents
|
||||
if (!$type) {
|
||||
$type = 'percentage';
|
||||
} elseif ($type !== 'percentage') {
|
||||
return false;
|
||||
}
|
||||
$num = (float)substr($part, 0, $length - 1);
|
||||
if ($num < 0) {
|
||||
$num = 0;
|
||||
}
|
||||
if ($num > 100) {
|
||||
$num = 100;
|
||||
}
|
||||
$new_parts[] = "$num%";
|
||||
} else {
|
||||
// handle integers
|
||||
if (!$type) {
|
||||
$type = 'integer';
|
||||
} elseif ($type !== 'integer') {
|
||||
return false;
|
||||
}
|
||||
$num = (int)$part;
|
||||
if ($num < 0) {
|
||||
$num = 0;
|
||||
}
|
||||
if ($num > 255) {
|
||||
$num = 255;
|
||||
}
|
||||
$new_parts[] = (string)$num;
|
||||
}
|
||||
}
|
||||
$new_triad = implode(',', $new_parts);
|
||||
$color = "rgb($new_triad)";
|
||||
} else {
|
||||
// hexadecimal handling
|
||||
if ($color[0] === '#') {
|
||||
$hex = substr($color, 1);
|
||||
} else {
|
||||
$hex = $color;
|
||||
$color = '#' . $color;
|
||||
}
|
||||
$length = strlen($hex);
|
||||
if ($length !== 3 && $length !== 6) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_xdigit($hex)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $color;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
48
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Composite.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Allows multiple validators to attempt to validate attribute.
|
||||
*
|
||||
* Composite is just what it sounds like: a composite of many validators.
|
||||
* This means that multiple HTMLPurifier_AttrDef objects will have a whack
|
||||
* at the string. If one of them passes, that's what is returned. This is
|
||||
* especially useful for CSS values, which often are a choice between
|
||||
* an enumerated set of predefined values or a flexible data type.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* List of objects that may process strings.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* @todo Make protected
|
||||
*/
|
||||
public $defs;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef[] $defs List of HTMLPurifier_AttrDef objects
|
||||
*/
|
||||
public function __construct($defs)
|
||||
{
|
||||
$this->defs = $defs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
foreach ($this->defs as $i => $def) {
|
||||
$result = $this->defs[$i]->validate($string, $config, $context);
|
||||
if ($result !== false) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
44
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Decorator which enables CSS properties to be disabled for specific elements.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
public $def;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
public $element;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $def Definition to wrap
|
||||
* @param string $element Element to deny
|
||||
*/
|
||||
public function __construct($def, $element)
|
||||
{
|
||||
$this->def = $def;
|
||||
$this->element = $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if CurrentToken is set and equal to $this->element
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if ($token && $token->name == $this->element) {
|
||||
return false;
|
||||
}
|
||||
return $this->def->validate($string, $config, $context);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
77
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Filter.php
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Microsoft's proprietary filter: CSS property
|
||||
* @note Currently supports the alpha filter. In the future, this will
|
||||
* probably need an extensible framework
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef_Integer
|
||||
*/
|
||||
protected $intValidator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->intValidator = new HTMLPurifier_AttrDef_Integer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($value, $config, $context)
|
||||
{
|
||||
$value = $this->parseCDATA($value);
|
||||
if ($value === 'none') {
|
||||
return $value;
|
||||
}
|
||||
// if we looped this we could support multiple filters
|
||||
$function_length = strcspn($value, '(');
|
||||
$function = trim(substr($value, 0, $function_length));
|
||||
if ($function !== 'alpha' &&
|
||||
$function !== 'Alpha' &&
|
||||
$function !== 'progid:DXImageTransform.Microsoft.Alpha'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
$cursor = $function_length + 1;
|
||||
$parameters_length = strcspn($value, ')', $cursor);
|
||||
$parameters = substr($value, $cursor, $parameters_length);
|
||||
$params = explode(',', $parameters);
|
||||
$ret_params = array();
|
||||
$lookup = array();
|
||||
foreach ($params as $param) {
|
||||
list($key, $value) = explode('=', $param);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
if (isset($lookup[$key])) {
|
||||
continue;
|
||||
}
|
||||
if ($key !== 'opacity') {
|
||||
continue;
|
||||
}
|
||||
$value = $this->intValidator->validate($value, $config, $context);
|
||||
if ($value === false) {
|
||||
continue;
|
||||
}
|
||||
$int = (int)$value;
|
||||
if ($int > 100) {
|
||||
$value = '100';
|
||||
}
|
||||
if ($int < 0) {
|
||||
$value = '0';
|
||||
}
|
||||
$ret_params[] = "$key=$value";
|
||||
$lookup[$key] = true;
|
||||
}
|
||||
$ret_parameters = implode(',', $ret_params);
|
||||
$ret_function = "$function($ret_parameters)";
|
||||
return $ret_function;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
176
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Font.php
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property font.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of validators
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* @note If we moved specific CSS property definitions to their own
|
||||
* classes instead of having them be assembled at run time by
|
||||
* CSSDefinition, this wouldn't be necessary. We'd instantiate
|
||||
* our own copies.
|
||||
*/
|
||||
protected $info = array();
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['font-style'] = $def->info['font-style'];
|
||||
$this->info['font-variant'] = $def->info['font-variant'];
|
||||
$this->info['font-weight'] = $def->info['font-weight'];
|
||||
$this->info['font-size'] = $def->info['font-size'];
|
||||
$this->info['line-height'] = $def->info['line-height'];
|
||||
$this->info['font-family'] = $def->info['font-family'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
static $system_fonts = array(
|
||||
'caption' => true,
|
||||
'icon' => true,
|
||||
'menu' => true,
|
||||
'message-box' => true,
|
||||
'small-caption' => true,
|
||||
'status-bar' => true
|
||||
);
|
||||
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if it's one of the keywords
|
||||
$lowercase_string = strtolower($string);
|
||||
if (isset($system_fonts[$lowercase_string])) {
|
||||
return $lowercase_string;
|
||||
}
|
||||
|
||||
$bits = explode(' ', $string); // bits to process
|
||||
$stage = 0; // this indicates what we're looking for
|
||||
$caught = array(); // which stage 0 properties have we caught?
|
||||
$stage_1 = array('font-style', 'font-variant', 'font-weight');
|
||||
$final = ''; // output
|
||||
|
||||
for ($i = 0, $size = count($bits); $i < $size; $i++) {
|
||||
if ($bits[$i] === '') {
|
||||
continue;
|
||||
}
|
||||
switch ($stage) {
|
||||
case 0: // attempting to catch font-style, font-variant or font-weight
|
||||
foreach ($stage_1 as $validator_name) {
|
||||
if (isset($caught[$validator_name])) {
|
||||
continue;
|
||||
}
|
||||
$r = $this->info[$validator_name]->validate(
|
||||
$bits[$i],
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
if ($r !== false) {
|
||||
$final .= $r . ' ';
|
||||
$caught[$validator_name] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// all three caught, continue on
|
||||
if (count($caught) >= 3) {
|
||||
$stage = 1;
|
||||
}
|
||||
if ($r !== false) {
|
||||
break;
|
||||
}
|
||||
case 1: // attempting to catch font-size and perhaps line-height
|
||||
$found_slash = false;
|
||||
if (strpos($bits[$i], '/') !== false) {
|
||||
list($font_size, $line_height) =
|
||||
explode('/', $bits[$i]);
|
||||
if ($line_height === '') {
|
||||
// ooh, there's a space after the slash!
|
||||
$line_height = false;
|
||||
$found_slash = true;
|
||||
}
|
||||
} else {
|
||||
$font_size = $bits[$i];
|
||||
$line_height = false;
|
||||
}
|
||||
$r = $this->info['font-size']->validate(
|
||||
$font_size,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
if ($r !== false) {
|
||||
$final .= $r;
|
||||
// attempt to catch line-height
|
||||
if ($line_height === false) {
|
||||
// we need to scroll forward
|
||||
for ($j = $i + 1; $j < $size; $j++) {
|
||||
if ($bits[$j] === '') {
|
||||
continue;
|
||||
}
|
||||
if ($bits[$j] === '/') {
|
||||
if ($found_slash) {
|
||||
return false;
|
||||
} else {
|
||||
$found_slash = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$line_height = $bits[$j];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// slash already found
|
||||
$found_slash = true;
|
||||
$j = $i;
|
||||
}
|
||||
if ($found_slash) {
|
||||
$i = $j;
|
||||
$r = $this->info['line-height']->validate(
|
||||
$line_height,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
if ($r !== false) {
|
||||
$final .= '/' . $r;
|
||||
}
|
||||
}
|
||||
$final .= ' ';
|
||||
$stage = 2;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
case 2: // attempting to catch font-family
|
||||
$font_family =
|
||||
implode(' ', array_slice($bits, $i, $size - $i));
|
||||
$r = $this->info['font-family']->validate(
|
||||
$font_family,
|
||||
$config,
|
||||
$context
|
||||
);
|
||||
if ($r !== false) {
|
||||
$final .= $r . ' ';
|
||||
// processing completed successfully
|
||||
return rtrim($final);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
219
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a font family list according to CSS spec
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
protected $mask = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->mask = '_- ';
|
||||
for ($c = 'a'; $c <= 'z'; $c++) {
|
||||
$this->mask .= $c;
|
||||
}
|
||||
for ($c = 'A'; $c <= 'Z'; $c++) {
|
||||
$this->mask .= $c;
|
||||
}
|
||||
for ($c = '0'; $c <= '9'; $c++) {
|
||||
$this->mask .= $c;
|
||||
} // cast-y, but should be fine
|
||||
// special bytes used by UTF-8
|
||||
for ($i = 0x80; $i <= 0xFF; $i++) {
|
||||
// We don't bother excluding invalid bytes in this range,
|
||||
// because the our restriction of well-formed UTF-8 will
|
||||
// prevent these from ever occurring.
|
||||
$this->mask .= chr($i);
|
||||
}
|
||||
|
||||
/*
|
||||
PHP's internal strcspn implementation is
|
||||
O(length of string * length of mask), making it inefficient
|
||||
for large masks. However, it's still faster than
|
||||
preg_match 8)
|
||||
for (p = s1;;) {
|
||||
spanp = s2;
|
||||
do {
|
||||
if (*spanp == c || p == s1_end) {
|
||||
return p - s1;
|
||||
}
|
||||
} while (spanp++ < (s2_end - 1));
|
||||
c = *++p;
|
||||
}
|
||||
*/
|
||||
// possible optimization: invert the mask.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
static $generic_names = array(
|
||||
'serif' => true,
|
||||
'sans-serif' => true,
|
||||
'monospace' => true,
|
||||
'fantasy' => true,
|
||||
'cursive' => true
|
||||
);
|
||||
$allowed_fonts = $config->get('CSS.AllowedFonts');
|
||||
|
||||
// assume that no font names contain commas in them
|
||||
$fonts = explode(',', $string);
|
||||
$final = '';
|
||||
foreach ($fonts as $font) {
|
||||
$font = trim($font);
|
||||
if ($font === '') {
|
||||
continue;
|
||||
}
|
||||
// match a generic name
|
||||
if (isset($generic_names[$font])) {
|
||||
if ($allowed_fonts === null || isset($allowed_fonts[$font])) {
|
||||
$final .= $font . ', ';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// match a quoted name
|
||||
if ($font[0] === '"' || $font[0] === "'") {
|
||||
$length = strlen($font);
|
||||
if ($length <= 2) {
|
||||
continue;
|
||||
}
|
||||
$quote = $font[0];
|
||||
if ($font[$length - 1] !== $quote) {
|
||||
continue;
|
||||
}
|
||||
$font = substr($font, 1, $length - 2);
|
||||
}
|
||||
|
||||
$font = $this->expandCSSEscape($font);
|
||||
|
||||
// $font is a pure representation of the font name
|
||||
|
||||
if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctype_alnum($font) && $font !== '') {
|
||||
// very simple font, allow it in unharmed
|
||||
$final .= $font . ', ';
|
||||
continue;
|
||||
}
|
||||
|
||||
// bugger out on whitespace. form feed (0C) really
|
||||
// shouldn't show up regardless
|
||||
$font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font);
|
||||
|
||||
// Here, there are various classes of characters which need
|
||||
// to be treated differently:
|
||||
// - Alphanumeric characters are essentially safe. We
|
||||
// handled these above.
|
||||
// - Spaces require quoting, though most parsers will do
|
||||
// the right thing if there aren't any characters that
|
||||
// can be misinterpreted
|
||||
// - Dashes rarely occur, but they fairly unproblematic
|
||||
// for parsing/rendering purposes.
|
||||
// The above characters cover the majority of Western font
|
||||
// names.
|
||||
// - Arbitrary Unicode characters not in ASCII. Because
|
||||
// most parsers give little thought to Unicode, treatment
|
||||
// of these codepoints is basically uniform, even for
|
||||
// punctuation-like codepoints. These characters can
|
||||
// show up in non-Western pages and are supported by most
|
||||
// major browsers, for example: "MS 明朝" is a
|
||||
// legitimate font-name
|
||||
// <http://ja.wikipedia.org/wiki/MS_明朝>. See
|
||||
// the CSS3 spec for more examples:
|
||||
// <http://www.w3.org/TR/2011/WD-css3-fonts-20110324/localizedfamilynames.png>
|
||||
// You can see live samples of these on the Internet:
|
||||
// <http://www.google.co.jp/search?q=font-family+MS+明朝|ゴシック>
|
||||
// However, most of these fonts have ASCII equivalents:
|
||||
// for example, 'MS Mincho', and it's considered
|
||||
// professional to use ASCII font names instead of
|
||||
// Unicode font names. Thanks Takeshi Terada for
|
||||
// providing this information.
|
||||
// The following characters, to my knowledge, have not been
|
||||
// used to name font names.
|
||||
// - Single quote. While theoretically you might find a
|
||||
// font name that has a single quote in its name (serving
|
||||
// as an apostrophe, e.g. Dave's Scribble), I haven't
|
||||
// been able to find any actual examples of this.
|
||||
// Internet Explorer's cssText translation (which I
|
||||
// believe is invoked by innerHTML) normalizes any
|
||||
// quoting to single quotes, and fails to escape single
|
||||
// quotes. (Note that this is not IE's behavior for all
|
||||
// CSS properties, just some sort of special casing for
|
||||
// font-family). So a single quote *cannot* be used
|
||||
// safely in the font-family context if there will be an
|
||||
// innerHTML/cssText translation. Note that Firefox 3.x
|
||||
// does this too.
|
||||
// - Double quote. In IE, these get normalized to
|
||||
// single-quotes, no matter what the encoding. (Fun
|
||||
// fact, in IE8, the 'content' CSS property gained
|
||||
// support, where they special cased to preserve encoded
|
||||
// double quotes, but still translate unadorned double
|
||||
// quotes into single quotes.) So, because their
|
||||
// fixpoint behavior is identical to single quotes, they
|
||||
// cannot be allowed either. Firefox 3.x displays
|
||||
// single-quote style behavior.
|
||||
// - Backslashes are reduced by one (so \\ -> \) every
|
||||
// iteration, so they cannot be used safely. This shows
|
||||
// up in IE7, IE8 and FF3
|
||||
// - Semicolons, commas and backticks are handled properly.
|
||||
// - The rest of the ASCII punctuation is handled properly.
|
||||
// We haven't checked what browsers do to unadorned
|
||||
// versions, but this is not important as long as the
|
||||
// browser doesn't /remove/ surrounding quotes (as IE does
|
||||
// for HTML).
|
||||
//
|
||||
// With these results in hand, we conclude that there are
|
||||
// various levels of safety:
|
||||
// - Paranoid: alphanumeric, spaces and dashes(?)
|
||||
// - International: Paranoid + non-ASCII Unicode
|
||||
// - Edgy: Everything except quotes, backslashes
|
||||
// - NoJS: Standards compliance, e.g. sod IE. Note that
|
||||
// with some judicious character escaping (since certain
|
||||
// types of escaping doesn't work) this is theoretically
|
||||
// OK as long as innerHTML/cssText is not called.
|
||||
// We believe that international is a reasonable default
|
||||
// (that we will implement now), and once we do more
|
||||
// extensive research, we may feel comfortable with dropping
|
||||
// it down to edgy.
|
||||
|
||||
// Edgy: alphanumeric, spaces, dashes, underscores and Unicode. Use of
|
||||
// str(c)spn assumes that the string was already well formed
|
||||
// Unicode (which of course it is).
|
||||
if (strspn($font, $this->mask) !== strlen($font)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Historical:
|
||||
// In the absence of innerHTML/cssText, these ugly
|
||||
// transforms don't pose a security risk (as \\ and \"
|
||||
// might--these escapes are not supported by most browsers).
|
||||
// We could try to be clever and use single-quote wrapping
|
||||
// when there is a double quote present, but I have choosen
|
||||
// not to implement that. (NOTE: you can reduce the amount
|
||||
// of escapes by one depending on what quoting style you use)
|
||||
// $font = str_replace('\\', '\\5C ', $font);
|
||||
// $font = str_replace('"', '\\22 ', $font);
|
||||
// $font = str_replace("'", '\\27 ', $font);
|
||||
|
||||
// font possibly with spaces, requires quoting
|
||||
$final .= "'$font', ";
|
||||
}
|
||||
$final = rtrim($final, ', ');
|
||||
if ($final === '') {
|
||||
return false;
|
||||
}
|
||||
return $final;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
32
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Ident.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates based on {ident} CSS grammar production
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Ident extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
|
||||
// early abort: '' and '0' (strings that convert to false) are invalid
|
||||
if (!$string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pattern = '/^(-?[A-Za-z_][A-Za-z_\-0-9]*)$/';
|
||||
if (!preg_match($pattern, $string)) {
|
||||
return false;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
56
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Decorator which enables !important to be used in CSS values.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_ImportantDecorator extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
public $def;
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
public $allow;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $def Definition to wrap
|
||||
* @param bool $allow Whether or not to allow !important
|
||||
*/
|
||||
public function __construct($def, $allow = false)
|
||||
{
|
||||
$this->def = $def;
|
||||
$this->allow = $allow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercepts and removes !important if necessary
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
// test for ! and important tokens
|
||||
$string = trim($string);
|
||||
$is_important = false;
|
||||
// :TODO: optimization: test directly for !important and ! important
|
||||
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
|
||||
$temp = rtrim(substr($string, 0, -9));
|
||||
// use a temp, because we might want to restore important
|
||||
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
|
||||
$string = rtrim(substr($temp, 0, -1));
|
||||
$is_important = true;
|
||||
}
|
||||
}
|
||||
$string = $this->def->validate($string, $config, $context);
|
||||
if ($this->allow && $is_important) {
|
||||
$string .= ' !important';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
77
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Length.php
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Represents a Length as defined by CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Length extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Length|string
|
||||
*/
|
||||
protected $min;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_Length|string
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Length|string $min Minimum length, or null for no bound. String is also acceptable.
|
||||
* @param HTMLPurifier_Length|string $max Maximum length, or null for no bound. String is also acceptable.
|
||||
*/
|
||||
public function __construct($min = null, $max = null)
|
||||
{
|
||||
$this->min = $min !== null ? HTMLPurifier_Length::make($min) : null;
|
||||
$this->max = $max !== null ? HTMLPurifier_Length::make($max) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
// Optimizations
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '0') {
|
||||
return '0';
|
||||
}
|
||||
if (strlen($string) === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = HTMLPurifier_Length::make($string);
|
||||
if (!$length->isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->min) {
|
||||
$c = $length->compareTo($this->min);
|
||||
if ($c === false) {
|
||||
return false;
|
||||
}
|
||||
if ($c < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->max) {
|
||||
$c = $length->compareTo($this->max);
|
||||
if ($c === false) {
|
||||
return false;
|
||||
}
|
||||
if ($c > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $length->toString();
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
112
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/ListStyle.php
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates shorthand CSS property list-style.
|
||||
* @warning Does not support url tokens that have internal spaces.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Local copy of validators.
|
||||
* @type HTMLPurifier_AttrDef[]
|
||||
* @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_Config $config
|
||||
*/
|
||||
public function __construct($config)
|
||||
{
|
||||
$def = $config->getCSSDefinition();
|
||||
$this->info['list-style-type'] = $def->info['list-style-type'];
|
||||
$this->info['list-style-position'] = $def->info['list-style-position'];
|
||||
$this->info['list-style-image'] = $def->info['list-style-image'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
// regular pre-processing
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// assumes URI doesn't have spaces in it
|
||||
$bits = explode(' ', strtolower($string)); // bits to process
|
||||
|
||||
$caught = array();
|
||||
$caught['type'] = false;
|
||||
$caught['position'] = false;
|
||||
$caught['image'] = false;
|
||||
|
||||
$i = 0; // number of catches
|
||||
$none = false;
|
||||
|
||||
foreach ($bits as $bit) {
|
||||
if ($i >= 3) {
|
||||
return;
|
||||
} // optimization bit
|
||||
if ($bit === '') {
|
||||
continue;
|
||||
}
|
||||
foreach ($caught as $key => $status) {
|
||||
if ($status !== false) {
|
||||
continue;
|
||||
}
|
||||
$r = $this->info['list-style-' . $key]->validate($bit, $config, $context);
|
||||
if ($r === false) {
|
||||
continue;
|
||||
}
|
||||
if ($r === 'none') {
|
||||
if ($none) {
|
||||
continue;
|
||||
} else {
|
||||
$none = true;
|
||||
}
|
||||
if ($key == 'image') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$caught[$key] = $r;
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
|
||||
// construct type
|
||||
if ($caught['type']) {
|
||||
$ret[] = $caught['type'];
|
||||
}
|
||||
|
||||
// construct image
|
||||
if ($caught['image']) {
|
||||
$ret[] = $caught['image'];
|
||||
}
|
||||
|
||||
// construct position
|
||||
if ($caught['position']) {
|
||||
$ret[] = $caught['position'];
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
return false;
|
||||
}
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
71
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Multiple.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Framework class for strings that involve multiple values.
|
||||
*
|
||||
* Certain CSS properties such as border-width and margin allow multiple
|
||||
* lengths to be specified. This class can take a vanilla border-width
|
||||
* definition and multiply it, usually into a max of four.
|
||||
*
|
||||
* @note Even though the CSS specification isn't clear about it, inherit
|
||||
* can only be used alone: it will never manifest as part of a multi
|
||||
* shorthand declaration. Thus, this class does not allow inherit.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* Instance of component definition to defer validation to.
|
||||
* @type HTMLPurifier_AttrDef
|
||||
* @todo Make protected
|
||||
*/
|
||||
public $single;
|
||||
|
||||
/**
|
||||
* Max number of values allowed.
|
||||
* @todo Make protected
|
||||
*/
|
||||
public $max;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $single HTMLPurifier_AttrDef to multiply
|
||||
* @param int $max Max number of values allowed (usually four)
|
||||
*/
|
||||
public function __construct($single, $max = 4)
|
||||
{
|
||||
$this->single = $single;
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
$parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n
|
||||
$length = count($parts);
|
||||
$final = '';
|
||||
for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) {
|
||||
if (ctype_space($parts[$i])) {
|
||||
continue;
|
||||
}
|
||||
$result = $this->single->validate($parts[$i], $config, $context);
|
||||
if ($result !== false) {
|
||||
$final .= $result . ' ';
|
||||
$num++;
|
||||
}
|
||||
}
|
||||
if ($final === '') {
|
||||
return false;
|
||||
}
|
||||
return rtrim($final);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
84
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Number.php
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a number as defined by the CSS spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Indicates whether or not only positive values are allowed.
|
||||
* @type bool
|
||||
*/
|
||||
protected $non_negative = false;
|
||||
|
||||
/**
|
||||
* @param bool $non_negative indicates whether negatives are forbidden
|
||||
*/
|
||||
public function __construct($non_negative = false)
|
||||
{
|
||||
$this->non_negative = $non_negative;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return string|bool
|
||||
* @warning Some contexts do not pass $config, $context. These
|
||||
* variables should not be used without checking HTMLPurifier_Length
|
||||
*/
|
||||
public function validate($number, $config, $context)
|
||||
{
|
||||
$number = $this->parseCDATA($number);
|
||||
|
||||
if ($number === '') {
|
||||
return false;
|
||||
}
|
||||
if ($number === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$sign = '';
|
||||
switch ($number[0]) {
|
||||
case '-':
|
||||
if ($this->non_negative) {
|
||||
return false;
|
||||
}
|
||||
$sign = '-';
|
||||
case '+':
|
||||
$number = substr($number, 1);
|
||||
}
|
||||
|
||||
if (ctype_digit($number)) {
|
||||
$number = ltrim($number, '0');
|
||||
return $number ? $sign . $number : '0';
|
||||
}
|
||||
|
||||
// Period is the only non-numeric character allowed
|
||||
if (strpos($number, '.') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
list($left, $right) = explode('.', $number, 2);
|
||||
|
||||
if ($left === '' && $right === '') {
|
||||
return false;
|
||||
}
|
||||
if ($left !== '' && !ctype_digit($left)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$left = ltrim($left, '0');
|
||||
$right = rtrim($right, '0');
|
||||
|
||||
if ($right === '') {
|
||||
return $left ? $sign . $left : '0';
|
||||
} elseif (!ctype_digit($right)) {
|
||||
return false;
|
||||
}
|
||||
return $sign . $left . '.' . $right;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
54
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/Percentage.php
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a Percentage as defined by the CSS spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_Percentage extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Instance to defer number validation to.
|
||||
* @type HTMLPurifier_AttrDef_CSS_Number
|
||||
*/
|
||||
protected $number_def;
|
||||
|
||||
/**
|
||||
* @param bool $non_negative Whether to forbid negative values
|
||||
*/
|
||||
public function __construct($non_negative = false)
|
||||
{
|
||||
$this->number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
$length = strlen($string);
|
||||
if ($length === 1) {
|
||||
return false;
|
||||
}
|
||||
if ($string[$length - 1] !== '%') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$number = substr($string, 0, $length - 1);
|
||||
$number = $this->number_def->validate($number, $config, $context);
|
||||
|
||||
if ($number === false) {
|
||||
return false;
|
||||
}
|
||||
return "$number%";
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
46
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/TextDecoration.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the value for the CSS property text-decoration
|
||||
* @note This class could be generalized into a version that acts sort of
|
||||
* like Enum except you can compound the allowed values.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_TextDecoration extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
static $allowed_values = array(
|
||||
'line-through' => true,
|
||||
'overline' => true,
|
||||
'underline' => true,
|
||||
);
|
||||
|
||||
$string = strtolower($this->parseCDATA($string));
|
||||
|
||||
if ($string === 'none') {
|
||||
return $string;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $string);
|
||||
$final = '';
|
||||
foreach ($parts as $part) {
|
||||
if (isset($allowed_values[$part])) {
|
||||
$final .= $part . ' ';
|
||||
}
|
||||
}
|
||||
$final = rtrim($final);
|
||||
if ($final === '') {
|
||||
return false;
|
||||
}
|
||||
return $final;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
74
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/CSS/URI.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a URI in CSS syntax, which uses url('http://example.com')
|
||||
* @note While theoretically speaking a URI in a CSS document could
|
||||
* be non-embedded, as of CSS2 there is no such usage so we're
|
||||
* generalizing it. This may need to be changed in the future.
|
||||
* @warning Since HTMLPurifier_AttrDef_CSS blindly uses semicolons as
|
||||
* the separator, you cannot put a literal semicolon in
|
||||
* in the URI. Try percent encoding it, in that case.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(true); // always embedded
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri_string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($uri_string, $config, $context)
|
||||
{
|
||||
// parse the URI out of the string and then pass it onto
|
||||
// the parent object
|
||||
|
||||
$uri_string = $this->parseCDATA($uri_string);
|
||||
if (strpos($uri_string, 'url(') !== 0) {
|
||||
return false;
|
||||
}
|
||||
$uri_string = substr($uri_string, 4);
|
||||
$new_length = strlen($uri_string) - 1;
|
||||
if ($uri_string[$new_length] != ')') {
|
||||
return false;
|
||||
}
|
||||
$uri = trim(substr($uri_string, 0, $new_length));
|
||||
|
||||
if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) {
|
||||
$quote = $uri[0];
|
||||
$new_length = strlen($uri) - 1;
|
||||
if ($uri[$new_length] !== $quote) {
|
||||
return false;
|
||||
}
|
||||
$uri = substr($uri, 1, $new_length - 1);
|
||||
}
|
||||
|
||||
$uri = $this->expandCSSEscape($uri);
|
||||
|
||||
$result = parent::validate($uri, $config, $context);
|
||||
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// extra sanity check; should have been done by URI
|
||||
$result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result);
|
||||
|
||||
// suspicious characters are ()'; we're going to percent encode
|
||||
// them for safety.
|
||||
$result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result);
|
||||
|
||||
// there's an extra bug where ampersands lose their escaping on
|
||||
// an innerHTML cycle, so a very unlucky query parameter could
|
||||
// then change the meaning of the URL. Unfortunately, there's
|
||||
// not much we can do about that...
|
||||
return "url(\"$result\")";
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
44
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Clone.php
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Dummy AttrDef that mimics another AttrDef, BUT it generates clones
|
||||
* with make.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Clone extends HTMLPurifier_AttrDef
|
||||
{
|
||||
/**
|
||||
* What we're cloning.
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
protected $clone;
|
||||
|
||||
/**
|
||||
* @param HTMLPurifier_AttrDef $clone
|
||||
*/
|
||||
public function __construct($clone)
|
||||
{
|
||||
$this->clone = $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $v
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($v, $config, $context)
|
||||
{
|
||||
return $this->clone->validate($v, $config, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return HTMLPurifier_AttrDef
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
return clone $this->clone;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
73
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Enum.php
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
// Enum = Enumerated
|
||||
/**
|
||||
* Validates a keyword against a list of valid values.
|
||||
* @warning The case-insensitive compare of this function uses PHP's
|
||||
* built-in strtolower and ctype_lower functions, which may
|
||||
* cause problems with international comparisons
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Lookup table of valid values.
|
||||
* @type array
|
||||
* @todo Make protected
|
||||
*/
|
||||
public $valid_values = array();
|
||||
|
||||
/**
|
||||
* Bool indicating whether or not enumeration is case sensitive.
|
||||
* @note In general this is always case insensitive.
|
||||
*/
|
||||
protected $case_sensitive = false; // values according to W3C spec
|
||||
|
||||
/**
|
||||
* @param array $valid_values List of valid values
|
||||
* @param bool $case_sensitive Whether or not case sensitive
|
||||
*/
|
||||
public function __construct($valid_values = array(), $case_sensitive = false)
|
||||
{
|
||||
$this->valid_values = array_flip($valid_values);
|
||||
$this->case_sensitive = $case_sensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
if (!$this->case_sensitive) {
|
||||
// we may want to do full case-insensitive libraries
|
||||
$string = ctype_lower($string) ? $string : strtolower($string);
|
||||
}
|
||||
$result = isset($this->valid_values[$string]);
|
||||
|
||||
return $result ? $string : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string In form of comma-delimited list of case-insensitive
|
||||
* valid values. Example: "foo,bar,baz". Prepend "s:" to make
|
||||
* case sensitive
|
||||
* @return HTMLPurifier_AttrDef_Enum
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') {
|
||||
$string = substr($string, 2);
|
||||
$sensitive = true;
|
||||
} else {
|
||||
$sensitive = false;
|
||||
}
|
||||
$values = explode(',', $string);
|
||||
return new HTMLPurifier_AttrDef_Enum($values, $sensitive);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
51
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Bool.php
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a boolean attribute
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
public $minimized = true;
|
||||
|
||||
/**
|
||||
* @param bool $name
|
||||
*/
|
||||
public function __construct($name = false)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
if (empty($string)) {
|
||||
return false;
|
||||
}
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string Name of attribute
|
||||
* @return HTMLPurifier_AttrDef_HTML_Bool
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
return new HTMLPurifier_AttrDef_HTML_Bool($string);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
48
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Class.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements special behavior for class attribute (normally NMTOKENS)
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Class extends HTMLPurifier_AttrDef_HTML_Nmtokens
|
||||
{
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function split($string, $config, $context)
|
||||
{
|
||||
// really, this twiddle should be lazy loaded
|
||||
$name = $config->getDefinition('HTML')->doctype->name;
|
||||
if ($name == "XHTML 1.1" || $name == "XHTML 2.0") {
|
||||
return parent::split($string, $config, $context);
|
||||
} else {
|
||||
return preg_split('/\s+/', $string);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tokens
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
protected function filter($tokens, $config, $context)
|
||||
{
|
||||
$allowed = $config->get('Attr.AllowedClasses');
|
||||
$forbidden = $config->get('Attr.ForbiddenClasses');
|
||||
$ret = array();
|
||||
foreach ($tokens as $token) {
|
||||
if (($allowed === null || isset($allowed[$token])) &&
|
||||
!isset($forbidden[$token]) &&
|
||||
// We need this O(n) check because of PHP's array
|
||||
// implementation that casts -0 to 0.
|
||||
!in_array($token, $ret, true)
|
||||
) {
|
||||
$ret[] = $token;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
51
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Color.php
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a color according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
static $colors = null;
|
||||
if ($colors === null) {
|
||||
$colors = $config->get('Core.ColorKeywords');
|
||||
}
|
||||
|
||||
$string = trim($string);
|
||||
|
||||
if (empty($string)) {
|
||||
return false;
|
||||
}
|
||||
$lower = strtolower($string);
|
||||
if (isset($colors[$lower])) {
|
||||
return $colors[$lower];
|
||||
}
|
||||
if ($string[0] === '#') {
|
||||
$hex = substr($string, 1);
|
||||
} else {
|
||||
$hex = $string;
|
||||
}
|
||||
|
||||
$length = strlen($hex);
|
||||
if ($length !== 3 && $length !== 6) {
|
||||
return false;
|
||||
}
|
||||
if (!ctype_xdigit($hex)) {
|
||||
return false;
|
||||
}
|
||||
if ($length === 3) {
|
||||
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
|
||||
}
|
||||
return "#$hex";
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
38
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/FrameTarget.php
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Special-case enum attribute definition that lazy loads allowed frame targets
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_FrameTarget extends HTMLPurifier_AttrDef_Enum
|
||||
{
|
||||
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
public $valid_values = false; // uninitialized value
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
protected $case_sensitive = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
if ($this->valid_values === false) {
|
||||
$this->valid_values = $config->get('Attr.AllowedFrameTargets');
|
||||
}
|
||||
return parent::validate($string, $config, $context);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
105
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/ID.php
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute ID.
|
||||
* @warning Even though this is the id processor, it
|
||||
* will ignore the directive Attr:IDBlacklist, since it will only
|
||||
* go according to the ID accumulator. Since the accumulator is
|
||||
* automatically generated, it will have already absorbed the
|
||||
* blacklist. If you're hacking around, make sure you use load()!
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
// selector is NOT a valid thing to use for IDREFs, because IDREFs
|
||||
// *must* target IDs that exist, whereas selector #ids do not.
|
||||
|
||||
/**
|
||||
* Determines whether or not we're validating an ID in a CSS
|
||||
* selector context.
|
||||
* @type bool
|
||||
*/
|
||||
protected $selector;
|
||||
|
||||
/**
|
||||
* @param bool $selector
|
||||
*/
|
||||
public function __construct($selector = false)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($id, $config, $context)
|
||||
{
|
||||
if (!$this->selector && !$config->get('Attr.EnableID')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = trim($id); // trim it first
|
||||
|
||||
if ($id === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$prefix = $config->get('Attr.IDPrefix');
|
||||
if ($prefix !== '') {
|
||||
$prefix .= $config->get('Attr.IDPrefixLocal');
|
||||
// prevent re-appending the prefix
|
||||
if (strpos($id, $prefix) !== 0) {
|
||||
$id = $prefix . $id;
|
||||
}
|
||||
} elseif ($config->get('Attr.IDPrefixLocal') !== '') {
|
||||
trigger_error(
|
||||
'%Attr.IDPrefixLocal cannot be used unless ' .
|
||||
'%Attr.IDPrefix is set',
|
||||
E_USER_WARNING
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->selector) {
|
||||
$id_accumulator =& $context->get('IDAccumulator');
|
||||
if (isset($id_accumulator->ids[$id])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// we purposely avoid using regex, hopefully this is faster
|
||||
|
||||
if (ctype_alpha($id)) {
|
||||
$result = true;
|
||||
} else {
|
||||
if (!ctype_alpha(@$id[0])) {
|
||||
return false;
|
||||
}
|
||||
// primitive style of regexps, I suppose
|
||||
$trim = trim(
|
||||
$id,
|
||||
'A..Za..z0..9:-._'
|
||||
);
|
||||
$result = ($trim === '');
|
||||
}
|
||||
|
||||
$regexp = $config->get('Attr.IDBlacklistRegexp');
|
||||
if ($regexp && preg_match($regexp, $id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->selector && $result) {
|
||||
$id_accumulator->add($id);
|
||||
}
|
||||
|
||||
// if no change was made to the ID, return the result
|
||||
// else, return the new id if stripping whitespace made it
|
||||
// valid, or return false.
|
||||
return $result ? $id : false;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
56
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Length.php
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the HTML type length (not to be confused with CSS's length).
|
||||
*
|
||||
* This accepts integer pixels or percentages as lengths for certain
|
||||
* HTML attributes.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrDef_HTML_Length extends HTMLPurifier_AttrDef_HTML_Pixels
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parent_result = parent::validate($string, $config, $context);
|
||||
if ($parent_result !== false) {
|
||||
return $parent_result;
|
||||
}
|
||||
|
||||
$length = strlen($string);
|
||||
$last_char = $string[$length - 1];
|
||||
|
||||
if ($last_char !== '%') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$points = substr($string, 0, $length - 1);
|
||||
|
||||
if (!is_numeric($points)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$points = (int)$points;
|
||||
|
||||
if ($points < 0) {
|
||||
return '0%';
|
||||
}
|
||||
if ($points > 100) {
|
||||
return '100%';
|
||||
}
|
||||
return ((string)$points) . '%';
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
72
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/LinkTypes.php
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a rel/rev link attribute against a directive of allowed values
|
||||
* @note We cannot use Enum because link types allow multiple
|
||||
* values.
|
||||
* @note Assumes link types are ASCII text
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Name config attribute to pull.
|
||||
* @type string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$configLookup = array(
|
||||
'rel' => 'AllowedRel',
|
||||
'rev' => 'AllowedRev'
|
||||
);
|
||||
if (!isset($configLookup[$name])) {
|
||||
trigger_error(
|
||||
'Unrecognized attribute name for link ' .
|
||||
'relationship.',
|
||||
E_USER_ERROR
|
||||
);
|
||||
return;
|
||||
}
|
||||
$this->name = $configLookup[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$allowed = $config->get('Attr.' . $this->name);
|
||||
if (empty($allowed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$string = $this->parseCDATA($string);
|
||||
$parts = explode(' ', $string);
|
||||
|
||||
// lookup to prevent duplicates
|
||||
$ret_lookup = array();
|
||||
foreach ($parts as $part) {
|
||||
$part = strtolower(trim($part));
|
||||
if (!isset($allowed[$part])) {
|
||||
continue;
|
||||
}
|
||||
$ret_lookup[$part] = true;
|
||||
}
|
||||
|
||||
if (empty($ret_lookup)) {
|
||||
return false;
|
||||
}
|
||||
$string = implode(' ', array_keys($ret_lookup));
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
60
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/MultiLength.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a MultiLength as defined by the HTML spec.
|
||||
*
|
||||
* A multilength is either a integer (pixel count), a percentage, or
|
||||
* a relative number.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_MultiLength extends HTMLPurifier_AttrDef_HTML_Length
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parent_result = parent::validate($string, $config, $context);
|
||||
if ($parent_result !== false) {
|
||||
return $parent_result;
|
||||
}
|
||||
|
||||
$length = strlen($string);
|
||||
$last_char = $string[$length - 1];
|
||||
|
||||
if ($last_char !== '*') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$int = substr($string, 0, $length - 1);
|
||||
|
||||
if ($int == '') {
|
||||
return '*';
|
||||
}
|
||||
if (!is_numeric($int)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$int = (int)$int;
|
||||
if ($int < 0) {
|
||||
return false;
|
||||
}
|
||||
if ($int == 0) {
|
||||
return '0';
|
||||
}
|
||||
if ($int == 1) {
|
||||
return '*';
|
||||
}
|
||||
return ((string)$int) . '*';
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
70
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Nmtokens.php
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates contents based on NMTOKENS attribute type.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Nmtokens extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
|
||||
// early abort: '' and '0' (strings that convert to false) are invalid
|
||||
if (!$string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tokens = $this->split($string, $config, $context);
|
||||
$tokens = $this->filter($tokens, $config, $context);
|
||||
if (empty($tokens)) {
|
||||
return false;
|
||||
}
|
||||
return implode(' ', $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a space separated list of tokens into its constituent parts.
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
protected function split($string, $config, $context)
|
||||
{
|
||||
// OPTIMIZABLE!
|
||||
// do the preg_match, capture all subpatterns for reformulation
|
||||
|
||||
// we don't support U+00A1 and up codepoints or
|
||||
// escaping because I don't know how to do that with regexps
|
||||
// and plus it would complicate optimization efforts (you never
|
||||
// see that anyway).
|
||||
$pattern = '/(?:(?<=\s)|\A)' . // look behind for space or string start
|
||||
'((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)' .
|
||||
'(?:(?=\s)|\z)/'; // look ahead for space or string end
|
||||
preg_match_all($pattern, $string, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method for removing certain tokens based on arbitrary criteria.
|
||||
* @note If we wanted to be really functional, we'd do an array_filter
|
||||
* with a callback. But... we're not.
|
||||
* @param array $tokens
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
protected function filter($tokens, $config, $context)
|
||||
{
|
||||
return $tokens;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
76
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/HTML/Pixels.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates an integer representation of pixels according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type int
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* @param int $max
|
||||
*/
|
||||
public function __construct($max = null)
|
||||
{
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
if ($string === '0') {
|
||||
return $string;
|
||||
}
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
$length = strlen($string);
|
||||
if (substr($string, $length - 2) == 'px') {
|
||||
$string = substr($string, 0, $length - 2);
|
||||
}
|
||||
if (!is_numeric($string)) {
|
||||
return false;
|
||||
}
|
||||
$int = (int)$string;
|
||||
|
||||
if ($int < 0) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// upper-bound value, extremely high values can
|
||||
// crash operating systems, see <http://ha.ckers.org/imagecrash.html>
|
||||
// WARNING, above link WILL crash you if you're using Windows
|
||||
|
||||
if ($this->max !== null && $int > $this->max) {
|
||||
return (string)$this->max;
|
||||
}
|
||||
return (string)$int;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return HTMLPurifier_AttrDef
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
if ($string === '') {
|
||||
$max = null;
|
||||
} else {
|
||||
$max = (int)$string;
|
||||
}
|
||||
$class = get_class($this);
|
||||
return new $class($max);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
91
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Integer.php
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates an integer.
|
||||
* @note While this class was modeled off the CSS definition, no currently
|
||||
* allowed CSS uses this type. The properties that do are: widows,
|
||||
* orphans, z-index, counter-increment, counter-reset. Some of the
|
||||
* HTML attributes, however, find use for a non-negative version of this.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Integer extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Whether or not negative values are allowed.
|
||||
* @type bool
|
||||
*/
|
||||
protected $negative = true;
|
||||
|
||||
/**
|
||||
* Whether or not zero is allowed.
|
||||
* @type bool
|
||||
*/
|
||||
protected $zero = true;
|
||||
|
||||
/**
|
||||
* Whether or not positive values are allowed.
|
||||
* @type bool
|
||||
*/
|
||||
protected $positive = true;
|
||||
|
||||
/**
|
||||
* @param $negative Bool indicating whether or not negative values are allowed
|
||||
* @param $zero Bool indicating whether or not zero is allowed
|
||||
* @param $positive Bool indicating whether or not positive values are allowed
|
||||
*/
|
||||
public function __construct($negative = true, $zero = true, $positive = true)
|
||||
{
|
||||
$this->negative = $negative;
|
||||
$this->zero = $zero;
|
||||
$this->positive = $positive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $integer
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($integer, $config, $context)
|
||||
{
|
||||
$integer = $this->parseCDATA($integer);
|
||||
if ($integer === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we could possibly simply typecast it to integer, but there are
|
||||
// certain fringe cases that must not return an integer.
|
||||
|
||||
// clip leading sign
|
||||
if ($this->negative && $integer[0] === '-') {
|
||||
$digits = substr($integer, 1);
|
||||
if ($digits === '0') {
|
||||
$integer = '0';
|
||||
} // rm minus sign for zero
|
||||
} elseif ($this->positive && $integer[0] === '+') {
|
||||
$digits = $integer = substr($integer, 1); // rm unnecessary plus
|
||||
} else {
|
||||
$digits = $integer;
|
||||
}
|
||||
|
||||
// test if it's numeric
|
||||
if (!ctype_digit($digits)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// perform scope tests
|
||||
if (!$this->zero && $integer == 0) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->positive && $integer > 0) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->negative && $integer < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $integer;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
86
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Lang.php
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the HTML attribute lang, effectively a language code.
|
||||
* @note Built according to RFC 3066, which obsoleted RFC 1766
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Lang extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = trim($string);
|
||||
if (!$string) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subtags = explode('-', $string);
|
||||
$num_subtags = count($subtags);
|
||||
|
||||
if ($num_subtags == 0) { // sanity check
|
||||
return false;
|
||||
}
|
||||
|
||||
// process primary subtag : $subtags[0]
|
||||
$length = strlen($subtags[0]);
|
||||
switch ($length) {
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
if (!($subtags[0] == 'x' || $subtags[0] == 'i')) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if (!ctype_alpha($subtags[0])) {
|
||||
return false;
|
||||
} elseif (!ctype_lower($subtags[0])) {
|
||||
$subtags[0] = strtolower($subtags[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$new_string = $subtags[0];
|
||||
if ($num_subtags == 1) {
|
||||
return $new_string;
|
||||
}
|
||||
|
||||
// process second subtag : $subtags[1]
|
||||
$length = strlen($subtags[1]);
|
||||
if ($length == 0 || ($length == 1 && $subtags[1] != 'x') || $length > 8 || !ctype_alnum($subtags[1])) {
|
||||
return $new_string;
|
||||
}
|
||||
if (!ctype_lower($subtags[1])) {
|
||||
$subtags[1] = strtolower($subtags[1]);
|
||||
}
|
||||
|
||||
$new_string .= '-' . $subtags[1];
|
||||
if ($num_subtags == 2) {
|
||||
return $new_string;
|
||||
}
|
||||
|
||||
// process all other subtags, index 2 and up
|
||||
for ($i = 2; $i < $num_subtags; $i++) {
|
||||
$length = strlen($subtags[$i]);
|
||||
if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) {
|
||||
return $new_string;
|
||||
}
|
||||
if (!ctype_lower($subtags[$i])) {
|
||||
$subtags[$i] = strtolower($subtags[$i]);
|
||||
}
|
||||
$new_string .= '-' . $subtags[$i];
|
||||
}
|
||||
return $new_string;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
53
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Switch.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Decorator that, depending on a token, switches between two definitions.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Switch
|
||||
{
|
||||
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
protected $withTag;
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_AttrDef
|
||||
*/
|
||||
protected $withoutTag;
|
||||
|
||||
/**
|
||||
* @param string $tag Tag name to switch upon
|
||||
* @param HTMLPurifier_AttrDef $with_tag Call if token matches tag
|
||||
* @param HTMLPurifier_AttrDef $without_tag Call if token doesn't match, or there is no token
|
||||
*/
|
||||
public function __construct($tag, $with_tag, $without_tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
$this->withTag = $with_tag;
|
||||
$this->withoutTag = $without_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$token = $context->get('CurrentToken', true);
|
||||
if (!$token || $token->name !== $this->tag) {
|
||||
return $this->withoutTag->validate($string, $config, $context);
|
||||
} else {
|
||||
return $this->withTag->validate($string, $config, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
21
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/Text.php
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates arbitrary text according to the HTML spec.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_Text extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
return $this->parseCDATA($string);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
111
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a URI as defined by RFC 3986.
|
||||
* @note Scheme-specific mechanics deferred to HTMLPurifier_URIScheme
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @type HTMLPurifier_URIParser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* @type bool
|
||||
*/
|
||||
protected $embedsResource;
|
||||
|
||||
/**
|
||||
* @param bool $embeds_resource Does the URI here result in an extra HTTP request?
|
||||
*/
|
||||
public function __construct($embeds_resource = false)
|
||||
{
|
||||
$this->parser = new HTMLPurifier_URIParser();
|
||||
$this->embedsResource = (bool)$embeds_resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return HTMLPurifier_AttrDef_URI
|
||||
*/
|
||||
public function make($string)
|
||||
{
|
||||
$embeds = ($string === 'embedded');
|
||||
return new HTMLPurifier_AttrDef_URI($embeds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($uri, $config, $context)
|
||||
{
|
||||
if ($config->get('URI.Disable')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$uri = $this->parseCDATA($uri);
|
||||
|
||||
// parse the URI
|
||||
$uri = $this->parser->parse($uri);
|
||||
if ($uri === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// add embedded flag to context for validators
|
||||
$context->register('EmbeddedURI', $this->embedsResource);
|
||||
|
||||
$ok = false;
|
||||
do {
|
||||
|
||||
// generic validation
|
||||
$result = $uri->validate($config, $context);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
||||
// chained filtering
|
||||
$uri_def = $config->getDefinition('URI');
|
||||
$result = $uri_def->filter($uri, $config, $context);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
||||
// scheme-specific validation
|
||||
$scheme_obj = $uri->getSchemeObj($config, $context);
|
||||
if (!$scheme_obj) {
|
||||
break;
|
||||
}
|
||||
if ($this->embedsResource && !$scheme_obj->browsable) {
|
||||
break;
|
||||
}
|
||||
$result = $scheme_obj->validate($uri, $config, $context);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Post chained filtering
|
||||
$result = $uri_def->postFilter($uri, $config, $context);
|
||||
if (!$result) {
|
||||
break;
|
||||
}
|
||||
|
||||
// survived gauntlet
|
||||
$ok = true;
|
||||
|
||||
} while (false);
|
||||
|
||||
$context->destroy('EmbeddedURI');
|
||||
if (!$ok) {
|
||||
return false;
|
||||
}
|
||||
// back to string
|
||||
return $uri->toString();
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
20
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI/Email.php
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
abstract class HTMLPurifier_AttrDef_URI_Email extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* Unpacks a mailbox into its display-name and address
|
||||
* @param string $string
|
||||
* @return mixed
|
||||
*/
|
||||
public function unpack($string)
|
||||
{
|
||||
// needs to be implemented
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// sub-implementations
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
29
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Primitive email validation class based on the regexp found at
|
||||
* http://www.regular-expressions.info/email.html
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI_Email_SimpleCheck extends HTMLPurifier_AttrDef_URI_Email
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
// no support for named mailboxes i.e. "Bob <bob@example.com>"
|
||||
// that needs more percent encoding to be done
|
||||
if ($string == '') {
|
||||
return false;
|
||||
}
|
||||
$string = trim($string);
|
||||
$result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string);
|
||||
return $result ? $string : false;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
128
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI/Host.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates a host according to the IPv4, IPv6 and DNS (future) specifications.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* IPv4 sub-validator.
|
||||
* @type HTMLPurifier_AttrDef_URI_IPv4
|
||||
*/
|
||||
protected $ipv4;
|
||||
|
||||
/**
|
||||
* IPv6 sub-validator.
|
||||
* @type HTMLPurifier_AttrDef_URI_IPv6
|
||||
*/
|
||||
protected $ipv6;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->ipv4 = new HTMLPurifier_AttrDef_URI_IPv4();
|
||||
$this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$length = strlen($string);
|
||||
// empty hostname is OK; it's usually semantically equivalent:
|
||||
// the default host as defined by a URI scheme is used:
|
||||
//
|
||||
// If the URI scheme defines a default for host, then that
|
||||
// default applies when the host subcomponent is undefined
|
||||
// or when the registered name is empty (zero length).
|
||||
if ($string === '') {
|
||||
return '';
|
||||
}
|
||||
if ($length > 1 && $string[0] === '[' && $string[$length - 1] === ']') {
|
||||
//IPv6
|
||||
$ip = substr($string, 1, $length - 2);
|
||||
$valid = $this->ipv6->validate($ip, $config, $context);
|
||||
if ($valid === false) {
|
||||
return false;
|
||||
}
|
||||
return '[' . $valid . ']';
|
||||
}
|
||||
|
||||
// need to do checks on unusual encodings too
|
||||
$ipv4 = $this->ipv4->validate($string, $config, $context);
|
||||
if ($ipv4 !== false) {
|
||||
return $ipv4;
|
||||
}
|
||||
|
||||
// A regular domain name.
|
||||
|
||||
// This doesn't match I18N domain names, but we don't have proper IRI support,
|
||||
// so force users to insert Punycode.
|
||||
|
||||
// There is not a good sense in which underscores should be
|
||||
// allowed, since it's technically not! (And if you go as
|
||||
// far to allow everything as specified by the DNS spec...
|
||||
// well, that's literally everything, modulo some space limits
|
||||
// for the components and the overall name (which, by the way,
|
||||
// we are NOT checking!). So we (arbitrarily) decide this:
|
||||
// let's allow underscores wherever we would have allowed
|
||||
// hyphens, if they are enabled. This is a pretty good match
|
||||
// for browser behavior, for example, a large number of browsers
|
||||
// cannot handle foo_.example.com, but foo_bar.example.com is
|
||||
// fairly well supported.
|
||||
$underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : '';
|
||||
|
||||
// The productions describing this are:
|
||||
$a = '[a-z]'; // alpha
|
||||
$an = '[a-z0-9]'; // alphanum
|
||||
$and = "[a-z0-9-$underscore]"; // alphanum | "-"
|
||||
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
|
||||
$domainlabel = "$an($and*$an)?";
|
||||
// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
|
||||
$toplabel = "$a($and*$an)?";
|
||||
// hostname = *( domainlabel "." ) toplabel [ "." ]
|
||||
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
// If we have Net_IDNA2 support, we can support IRIs by
|
||||
// punycoding them. (This is the most portable thing to do,
|
||||
// since otherwise we have to assume browsers support
|
||||
|
||||
if ($config->get('Core.EnableIDNA')) {
|
||||
$idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
|
||||
// we need to encode each period separately
|
||||
$parts = explode('.', $string);
|
||||
try {
|
||||
$new_parts = array();
|
||||
foreach ($parts as $part) {
|
||||
$encodable = false;
|
||||
for ($i = 0, $c = strlen($part); $i < $c; $i++) {
|
||||
if (ord($part[$i]) > 0x7a) {
|
||||
$encodable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$encodable) {
|
||||
$new_parts[] = $part;
|
||||
} else {
|
||||
$new_parts[] = $idna->encode($part);
|
||||
}
|
||||
}
|
||||
$string = implode('.', $new_parts);
|
||||
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
|
||||
return $string;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// XXX error reporting
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
45
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI/IPv4.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates an IPv4 address
|
||||
* @author Feyd @ forums.devnetwork.net (public domain)
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI_IPv4 extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* IPv4 regex, protected so that IPv6 can reuse it.
|
||||
* @type string
|
||||
*/
|
||||
protected $ip4;
|
||||
|
||||
/**
|
||||
* @param string $aIP
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($aIP, $config, $context)
|
||||
{
|
||||
if (!$this->ip4) {
|
||||
$this->_loadRegex();
|
||||
}
|
||||
|
||||
if (preg_match('#^' . $this->ip4 . '$#s', $aIP)) {
|
||||
return $aIP;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy load function to prevent regex from being stuffed in
|
||||
* cache.
|
||||
*/
|
||||
protected function _loadRegex()
|
||||
{
|
||||
$oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255
|
||||
$this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})";
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
89
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrDef/URI/IPv6.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates an IPv6 address.
|
||||
* @author Feyd @ forums.devnetwork.net (public domain)
|
||||
* @note This function requires brackets to have been removed from address
|
||||
* in URI.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $aIP
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($aIP, $config, $context)
|
||||
{
|
||||
if (!$this->ip4) {
|
||||
$this->_loadRegex();
|
||||
}
|
||||
|
||||
$original = $aIP;
|
||||
|
||||
$hex = '[0-9a-fA-F]';
|
||||
$blk = '(?:' . $hex . '{1,4})';
|
||||
$pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128
|
||||
|
||||
// prefix check
|
||||
if (strpos($aIP, '/') !== false) {
|
||||
if (preg_match('#' . $pre . '$#s', $aIP, $find)) {
|
||||
$aIP = substr($aIP, 0, 0 - strlen($find[0]));
|
||||
unset($find);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// IPv4-compatiblity check
|
||||
if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) {
|
||||
$aIP = substr($aIP, 0, 0 - strlen($find[0]));
|
||||
$ip = explode('.', $find[0]);
|
||||
$ip = array_map('dechex', $ip);
|
||||
$aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3];
|
||||
unset($find, $ip);
|
||||
}
|
||||
|
||||
// compression check
|
||||
$aIP = explode('::', $aIP);
|
||||
$c = count($aIP);
|
||||
if ($c > 2) {
|
||||
return false;
|
||||
} elseif ($c == 2) {
|
||||
list($first, $second) = $aIP;
|
||||
$first = explode(':', $first);
|
||||
$second = explode(':', $second);
|
||||
|
||||
if (count($first) + count($second) > 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (count($first) < 8) {
|
||||
array_push($first, '0');
|
||||
}
|
||||
|
||||
array_splice($first, 8 - count($second), 8, $second);
|
||||
$aIP = $first;
|
||||
unset($first, $second);
|
||||
} else {
|
||||
$aIP = explode(':', $aIP[0]);
|
||||
}
|
||||
$c = count($aIP);
|
||||
|
||||
if ($c != 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All the pieces should be 16-bit hex strings. Are they?
|
||||
foreach ($aIP as $piece) {
|
||||
if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $original;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
60
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Processes an entire attribute array for corrections needing multiple values.
|
||||
*
|
||||
* Occasionally, a certain attribute will need to be removed and popped onto
|
||||
* another value. Instead of creating a complex return syntax for
|
||||
* HTMLPurifier_AttrDef, we just pass the whole attribute array to a
|
||||
* specialized object and have that do the special work. That is the
|
||||
* family of HTMLPurifier_AttrTransform.
|
||||
*
|
||||
* An attribute transformation can be assigned to run before or after
|
||||
* HTMLPurifier_AttrDef validation. See HTMLPurifier_HTMLDefinition for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
abstract class HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
/**
|
||||
* Abstract: makes changes to the attributes dependent on multiple values.
|
||||
*
|
||||
* @param array $attr Assoc array of attributes, usually from
|
||||
* HTMLPurifier_Token_Tag::$attr
|
||||
* @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object.
|
||||
* @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object
|
||||
* @return array Processed attribute array.
|
||||
*/
|
||||
abstract public function transform($attr, $config, $context);
|
||||
|
||||
/**
|
||||
* Prepends CSS properties to the style attribute, creating the
|
||||
* attribute if it doesn't exist.
|
||||
* @param array &$attr Attribute array to process (passed by reference)
|
||||
* @param string $css CSS to prepend
|
||||
*/
|
||||
public function prependCSS(&$attr, $css)
|
||||
{
|
||||
$attr['style'] = isset($attr['style']) ? $attr['style'] : '';
|
||||
$attr['style'] = $css . $attr['style'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and removes an attribute
|
||||
* @param array &$attr Attribute array to process (passed by reference)
|
||||
* @param mixed $key Key of attribute to confiscate
|
||||
* @return mixed
|
||||
*/
|
||||
public function confiscateAttr(&$attr, $key)
|
||||
{
|
||||
if (!isset($attr[$key])) {
|
||||
return null;
|
||||
}
|
||||
$value = $attr[$key];
|
||||
unset($attr[$key]);
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
28
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/Background.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pre-transform that changes proprietary background attribute to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_Background extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr['background'])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
$background = $this->confiscateAttr($attr, 'background');
|
||||
// some validation should happen here
|
||||
|
||||
$this->prependCSS($attr, "background-image:url($background);");
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
27
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/BdoDir.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
// this MUST be placed in post, as it assumes that any value in dir is valid
|
||||
|
||||
/**
|
||||
* Post-trasnform that ensures that bdo tags have the dir attribute set.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (isset($attr['dir'])) {
|
||||
return $attr;
|
||||
}
|
||||
$attr['dir'] = $config->get('Attr.DefaultTextDir');
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
28
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/BgColor.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated bgcolor attribute to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BgColor extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr['bgcolor'])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
$bgcolor = $this->confiscateAttr($attr, 'bgcolor');
|
||||
// some validation should happen here
|
||||
|
||||
$this->prependCSS($attr, "background-color:$bgcolor;");
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
47
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/BoolToCSS.php
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pre-transform that changes converts a boolean attribute to fixed CSS
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_BoolToCSS extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* Name of boolean attribute that is trigger.
|
||||
* @type string
|
||||
*/
|
||||
protected $attr;
|
||||
|
||||
/**
|
||||
* CSS declarations to add to style, needs trailing semicolon.
|
||||
* @type string
|
||||
*/
|
||||
protected $css;
|
||||
|
||||
/**
|
||||
* @param string $attr attribute name to convert from
|
||||
* @param string $css CSS declarations to add to style (needs semicolon)
|
||||
*/
|
||||
public function __construct($attr, $css)
|
||||
{
|
||||
$this->attr = $attr;
|
||||
$this->css = $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr[$this->attr])) {
|
||||
return $attr;
|
||||
}
|
||||
unset($attr[$this->attr]);
|
||||
$this->prependCSS($attr, $this->css);
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
26
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/Border.php
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated border attribute to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_Border extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr['border'])) {
|
||||
return $attr;
|
||||
}
|
||||
$border_width = $this->confiscateAttr($attr, 'border');
|
||||
// some validation should happen here
|
||||
$this->prependCSS($attr, "border:{$border_width}px solid;");
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
68
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/EnumToCSS.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Generic pre-transform that converts an attribute with a fixed number of
|
||||
* values (enumerated) to CSS.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_EnumToCSS extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* Name of attribute to transform from.
|
||||
* @type string
|
||||
*/
|
||||
protected $attr;
|
||||
|
||||
/**
|
||||
* Lookup array of attribute values to CSS.
|
||||
* @type array
|
||||
*/
|
||||
protected $enumToCSS = array();
|
||||
|
||||
/**
|
||||
* Case sensitivity of the matching.
|
||||
* @type bool
|
||||
* @warning Currently can only be guaranteed to work with ASCII
|
||||
* values.
|
||||
*/
|
||||
protected $caseSensitive = false;
|
||||
|
||||
/**
|
||||
* @param string $attr Attribute name to transform from
|
||||
* @param array $enum_to_css Lookup array of attribute values to CSS
|
||||
* @param bool $case_sensitive Case sensitivity indicator, default false
|
||||
*/
|
||||
public function __construct($attr, $enum_to_css, $case_sensitive = false)
|
||||
{
|
||||
$this->attr = $attr;
|
||||
$this->enumToCSS = $enum_to_css;
|
||||
$this->caseSensitive = (bool)$case_sensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr[$this->attr])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
$value = trim($attr[$this->attr]);
|
||||
unset($attr[$this->attr]);
|
||||
|
||||
if (!$this->caseSensitive) {
|
||||
$value = strtolower($value);
|
||||
}
|
||||
|
||||
if (!isset($this->enumToCSS[$value])) {
|
||||
return $attr;
|
||||
}
|
||||
$this->prependCSS($attr, $this->enumToCSS[$value]);
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
48
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/ImgRequired.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
// must be called POST validation
|
||||
|
||||
/**
|
||||
* Transform that supplies default values for the src and alt attributes
|
||||
* in img tags, as well as prevents the img tag from being removed
|
||||
* because of a missing alt tag. This needs to be registered as both
|
||||
* a pre and post attribute transform.
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ImgRequired extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
$src = true;
|
||||
if (!isset($attr['src'])) {
|
||||
if ($config->get('Core.RemoveInvalidImg')) {
|
||||
return $attr;
|
||||
}
|
||||
$attr['src'] = $config->get('Attr.DefaultInvalidImage');
|
||||
$src = false;
|
||||
}
|
||||
|
||||
if (!isset($attr['alt'])) {
|
||||
if ($src) {
|
||||
$alt = $config->get('Attr.DefaultImageAlt');
|
||||
if ($alt === null) {
|
||||
// truncate if the alt is too long
|
||||
$attr['alt'] = substr(basename($attr['src']), 0, 40);
|
||||
} else {
|
||||
$attr['alt'] = $alt;
|
||||
}
|
||||
} else {
|
||||
$attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt');
|
||||
}
|
||||
}
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||
61
inc/3rdparty/htmlpurifier/HTMLPurifier/AttrTransform/ImgSpace.php
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pre-transform that changes deprecated hspace and vspace attributes to CSS
|
||||
*/
|
||||
class HTMLPurifier_AttrTransform_ImgSpace extends HTMLPurifier_AttrTransform
|
||||
{
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
protected $attr;
|
||||
|
||||
/**
|
||||
* @type array
|
||||
*/
|
||||
protected $css = array(
|
||||
'hspace' => array('left', 'right'),
|
||||
'vspace' => array('top', 'bottom')
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $attr
|
||||
*/
|
||||
public function __construct($attr)
|
||||
{
|
||||
$this->attr = $attr;
|
||||
if (!isset($this->css[$attr])) {
|
||||
trigger_error(htmlspecialchars($attr) . ' is not valid space attribute');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attr
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return array
|
||||
*/
|
||||
public function transform($attr, $config, $context)
|
||||
{
|
||||
if (!isset($attr[$this->attr])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
$width = $this->confiscateAttr($attr, $this->attr);
|
||||
// some validation could happen here
|
||||
|
||||
if (!isset($this->css[$this->attr])) {
|
||||
return $attr;
|
||||
}
|
||||
|
||||
$style = '';
|
||||
foreach ($this->css[$this->attr] as $suffix) {
|
||||
$property = "margin-$suffix";
|
||||
$style .= "$property:{$width}px;";
|
||||
}
|
||||
$this->prependCSS($attr, $style);
|
||||
return $attr;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
||||