forked from wallabag/wallabag
Compare commits
1139 Commits
1.2.0
...
2.0.0-alph
| Author | SHA1 | Date | |
|---|---|---|---|
| 1db9d411c5 | |||
| 451bad02f0 | |||
| b004a236ba | |||
| 1a5f7e2d88 | |||
| 5e98404dfb | |||
| 463573bf69 | |||
| 5def3f5862 | |||
| 71e51207ce | |||
| 1137fae94d | |||
| d2fcbf5d84 | |||
| 19c283140e | |||
| 89ee994f77 | |||
| a78d6afeaa | |||
| 4d5fd9be81 | |||
| 40f59b219b | |||
| 497e0cad7c | |||
| b026d3b115 | |||
| 616f9fea26 | |||
| a3bcd60a37 | |||
| fb96ea8845 | |||
| e610143f51 | |||
| af43bd3767 | |||
| 3f7a62908c | |||
| a1691859ca | |||
| 9c08a891f9 | |||
| f1e29e69cb | |||
| 558d9aabab | |||
| 75c3478a0c | |||
| 49e564ec15 | |||
| e643992350 | |||
| b125ed0394 | |||
| c6da9bea71 | |||
| 50243f0e34 | |||
| d13de40db6 | |||
| a1413a3da9 | |||
| fad316151c | |||
| 8c55a9e6c9 | |||
| 230413bdd1 | |||
| dc1c2debfb | |||
| a754db33c9 | |||
| 7083d183b9 | |||
| 8bb1f3d69a | |||
| f90af145ca | |||
| bccb5bba75 | |||
| 7d6c3edcdd | |||
| ec00964de2 | |||
| 7244d6cb61 | |||
| 83aaf84195 | |||
| 16a3d04cbd | |||
| f9d5155abf | |||
| b45c188516 | |||
| f506da40e2 | |||
| 3b84dc08fc | |||
| 78f66dcc52 | |||
| c937de3443 | |||
| 2b7a488917 | |||
| e177976099 | |||
| 89659c9eae | |||
| 109d67dbb1 | |||
| 6682139ec5 | |||
| e6f55346fd | |||
| eccf5eb2e0 | |||
| 1dbcd63b59 | |||
| 4793ee6509 | |||
| 6eebd8c909 | |||
| 0ab7404f93 | |||
| 4fcb7eaf13 | |||
| 8ce32af612 | |||
| 34437f408c | |||
| ab4aeb8bd8 | |||
| fdab81e910 | |||
| c3fdbcc60f | |||
| e62d27ff9b | |||
| 8b8cdabc89 | |||
| bdd23b076a | |||
| 7b2d336893 | |||
| 443cecd2d8 | |||
| b71ebd9af9 | |||
| 22ed64522a | |||
| 2e02b50409 | |||
| a3b4e8a2c0 | |||
| d5e9a99ce6 | |||
| 68568bf0b7 | |||
| 02947111c0 | |||
| e68d9179a1 | |||
| c713273619 | |||
| 3f357ee241 | |||
| c3cb46809b | |||
| 72ea6dd1a7 | |||
| 54f2b4a254 | |||
| 3162601c59 | |||
| 6819604185 | |||
| f967422fae | |||
| 428af5a8c3 | |||
| fd72e99d53 | |||
| 2a2903ceaa | |||
| fac3f8abfa | |||
| e40ff14d7d | |||
| a2cdaa8cdd | |||
| 4a230f9844 | |||
| 5f246a5543 | |||
| 2ba06b1ee2 | |||
| 3c5b025ac3 | |||
| ceb79aa016 | |||
| 925d8ab316 | |||
| d5b28518e9 | |||
| 0a3a5f6cd7 | |||
| ab2c93c7eb | |||
| 727b39a90e | |||
| c14a7c4251 | |||
| c37381b946 | |||
| 790d18a319 | |||
| 6fd3d82c01 | |||
| fcb3faf109 | |||
| d75a9fa38b | |||
| 0e7cf1fc50 | |||
| 9cc6bd87fe | |||
| 80127e4fb1 | |||
| 4ca0c9139c | |||
| a64f1d9f2d | |||
| bac5a34552 | |||
| a737d2a0ee | |||
| 545b852f46 | |||
| 392f4a2681 | |||
| 120544cccd | |||
| 82b07eb272 | |||
| c2257428b2 | |||
| 8ba913d87a | |||
| 06fdfd025e | |||
| d990dc6f05 | |||
| bdf39ff10d | |||
| 2ac2e0bc2b | |||
| 1a0ea1f35a | |||
| 43e6f47d5b | |||
| 9f1d650ae8 | |||
| b69fc0628a | |||
| a8596c35c8 | |||
| a15692b1b7 | |||
| 6622cf9968 | |||
| 7fc14130c7 | |||
| 579764b264 | |||
| 3e1f25e22f | |||
| 5a58461491 | |||
| 773ed2e7a6 | |||
| 496f21e6fa | |||
| 053b9568b2 | |||
| 930334cd6d | |||
| 2686457448 | |||
| fedaf00537 | |||
| ea8da8c6d5 | |||
| 95135988f9 | |||
| d85454fbf8 | |||
| 728a432850 | |||
| f59601fced | |||
| 0e654f6273 | |||
| f48a018929 | |||
| b958d9e59b | |||
| 4919584b87 | |||
| 1473e8c9fb | |||
| 47cadf36c8 | |||
| 20a69dffe7 | |||
| 009696d0a8 | |||
| e9d5c2bf02 | |||
| 946d6a5124 | |||
| a6523cfe86 | |||
| c54ea989a3 | |||
| 342f0cc55a | |||
| 0e7650683d | |||
| 768303a573 | |||
| 0bc2baa65c | |||
| b7dd5f824c | |||
| 54139268f8 | |||
| 44a16e82d8 | |||
| d0b90fbe18 | |||
| 55333dfd21 | |||
| 47e12c3677 | |||
| 3f3fbef11f | |||
| 48ffc5a4b6 | |||
| 6ecdd48a3f | |||
| b17874a7d5 | |||
| 308db01684 | |||
| b1a65df9df | |||
| 8d9b8912af | |||
| 4ab58dcf6c | |||
| 9e07dc982c | |||
| 9948d899d3 | |||
| 53e121881b | |||
| 7e63b892f9 | |||
| 9fb6ac830f | |||
| 9b9b05008a | |||
| ac9d58211e | |||
| 3cf22a0541 | |||
| 82d6d9cb06 | |||
| 75e9d1df03 | |||
| 170746f99d | |||
| 51d9699fa1 | |||
| 2878416f8b | |||
| 4346a86068 | |||
| 399bd777d7 | |||
| 2f3c816579 | |||
| 9a014e48d6 | |||
| 98510a4189 | |||
| c7d3bf1671 | |||
| 4d6e818e40 | |||
| 1cbef2d3b5 | |||
| 04aaa199b7 | |||
| 132f614dee | |||
| 9744e97131 | |||
| 769e19dc4a | |||
| e3c34bfc06 | |||
| d6fa2f70ac | |||
| 276a1e9d3f | |||
| 164bd80118 | |||
| c844dc0c50 | |||
| 1a93ee423b | |||
| 7d74a2f32b | |||
| 14d7a69b8c | |||
| 34c06cabef | |||
| 0ee043f745 | |||
| 371ac69a6b | |||
| 2385f891e5 | |||
| 0c83fd5994 | |||
| f98a2a0fc3 | |||
| bdf2add2e8 | |||
| 3e6b7ea0e9 | |||
| 6141388969 | |||
| 2d733277e6 | |||
| a05be8abec | |||
| d0c2243b10 | |||
| 6894d48e03 | |||
| f37d1427a1 | |||
| 6e22bd737b | |||
| bcf53ab75b | |||
| a24f2c8808 | |||
| 48b67328e2 | |||
| efad7e53a1 | |||
| 2ab8cb6816 | |||
| db2b4bf678 | |||
| b0cce9e636 | |||
| 1df1204d94 | |||
| 6ee416a069 | |||
| 0ca374e6a1 | |||
| d8f9f37ab2 | |||
| 092ca70725 | |||
| a36737f485 | |||
| 46bbd8d321 | |||
| 6c87418ff0 | |||
| 1bd12b6229 | |||
| 0a018fe039 | |||
| 6d37a7e6c1 | |||
| b3dc0749d3 | |||
| 2691cf0438 | |||
| 1d14779154 | |||
| aa4d6562c1 | |||
| 0ed6302212 | |||
| 0f00688096 | |||
| 73b7744383 | |||
| 8378485e33 | |||
| ba7b9d48d4 | |||
| 3e30422cda | |||
| 495aecfe74 | |||
| 71798e4ec4 | |||
| 32da2a70ef | |||
| fca3c75723 | |||
| dcae2fc25d | |||
| 0e7971d835 | |||
| c641baad0e | |||
| 732c2ad897 | |||
| 0bf99bb144 | |||
| 0bd2cb1ecd | |||
| e4977b8a86 | |||
| c0d9eba07f | |||
| d9085c63e3 | |||
| 7781faa0b0 | |||
| 78cedc2262 | |||
| 4d85d7e9ba | |||
| 7a577c519f | |||
| 55f58c9c5e | |||
| 2f6a596760 | |||
| 8c7e0f95b9 | |||
| d9b7175593 | |||
| 59f18f9a85 | |||
| 9ca5fd43f9 | |||
| f170f31594 | |||
| 874e3e10a4 | |||
| f8c2736a10 | |||
| 70b54da2b1 | |||
| c9fa9677c1 | |||
| fa8d563934 | |||
| 19aee7cd54 | |||
| 2725de8efb | |||
| 91f78f26f2 | |||
| 2734044aca | |||
| 0536b809b0 | |||
| e1dd7f70c5 | |||
| f5deb024a2 | |||
| 68c6f1bd7f | |||
| da93261a7d | |||
| 3d2b2d62be | |||
| eb3bd7efb7 | |||
| f59f45d740 | |||
| 017e20895f | |||
| 2c0ffcf397 | |||
| 3d3368cfd5 | |||
| 92504e0dd4 | |||
| 11204db45a | |||
| d4c029f46e | |||
| c5e8ba25bb | |||
| eaf95758dc | |||
| 7ffb1e80bf | |||
| 5078e8360a | |||
| d29bfaf139 | |||
| 2a94b1d1b7 | |||
| cbce162b40 | |||
| fb8389f463 | |||
| 970c40bb93 | |||
| 0ac38198ab | |||
| 653e8be4c1 | |||
| 89c03230c3 | |||
| 3b815d2de5 | |||
| d91691573f | |||
| 7812f508bc | |||
| 5f09650eef | |||
| 8af35ad932 | |||
| 9c0c882006 | |||
| 94f2364cd8 | |||
| 8125b415d8 | |||
| d01db0c71d | |||
| ed4d5cf2d7 | |||
| 427b61a35b | |||
| 7f2d9f9613 | |||
| c64a14787d | |||
| 02b225a82e | |||
| 15d33c24dc | |||
| 2f69eb4afa | |||
| 29c4517f7a | |||
| be463487cc | |||
| 905ae369bd | |||
| c8dee95396 | |||
| c0284f6182 | |||
| 93e28e4d2e | |||
| 5644c2d88e | |||
| de00c9208d | |||
| 2c093b03de | |||
| 9e0fff7cb0 | |||
| 77bb7b92a2 | |||
| 3bb7c5ffec | |||
| c2e2906c8d | |||
| bc782eaa72 | |||
| 34d15eb4d0 | |||
| 1b0e6e9ae6 | |||
| 61b9fdd5e4 | |||
| eacaf7f864 | |||
| 6079aaa33d | |||
| 6e334aba68 | |||
| 42a9064620 | |||
| 889249804f | |||
| c5772d118f | |||
| 2e45e7bebc | |||
| 8394ab4619 | |||
| 4cfbd5d893 | |||
| 7df80cb32c | |||
| daacffefa6 | |||
| 1990517b22 | |||
| c3235553dd | |||
| 71691fe44a | |||
| aa6e27cf4f | |||
| 4ffc77d9f5 | |||
| fdcbdda1ad | |||
| 367664ee87 | |||
| e11e03cb32 | |||
| 3ba208b205 | |||
| 127915f4ea | |||
| 03493be075 | |||
| 843dbe5195 | |||
| a8c90c5c1b | |||
| a65f5d5563 | |||
| 27f15aa4ca | |||
| f8bf895254 | |||
| 589dce52c6 | |||
| 38ba7ed972 | |||
| 3e5a342f65 | |||
| e4788de51e | |||
| 569f8d6851 | |||
| 19f2f11ee8 | |||
| 9e11bfa4a6 | |||
| 7dfc3c2b58 | |||
| 80709502c7 | |||
| 2cdb0b8f40 | |||
| b2d9357c78 | |||
| c4b1e79018 | |||
| dc61832a9e | |||
| 33767049a5 | |||
| 0c678cf24a | |||
| b9ec99e25b | |||
| d692b3b08d | |||
| 6b767d1cc0 | |||
| ad4d1caa9e | |||
| b84a80559a | |||
| 163eae0bb1 | |||
| bd9f08157c | |||
| 9d50517cea | |||
| 2b9fe72b39 | |||
| 93fd4692f6 | |||
| 0440249631 | |||
| 3eb951572d | |||
| 9de6a0a7cc | |||
| 19875ef0da | |||
| 00fcfd299b | |||
| 79e051a1f2 | |||
| 97a2dd74c8 | |||
| 8d6ff10e8e | |||
| 9a5c1bc62a | |||
| 6ad93dff69 | |||
| c78c1a3f08 | |||
| 9e7f6caf03 | |||
| 820d81aa61 | |||
| 3329f1bf3d | |||
| 90c67dbd12 | |||
| 96b2c59c04 | |||
| 3d99ce9dad | |||
| 99410a21eb | |||
| 1345a10788 | |||
| f3052b4542 | |||
| e342acf7ba | |||
| 2b17e0aa77 | |||
| dda7884ace | |||
| 10939766de | |||
| a20f96b76d | |||
| adf17b677e | |||
| 894cd087f4 | |||
| 44f1fef018 | |||
| 170a1407fe | |||
| b68f0a81e5 | |||
| 7fe8a9adc4 | |||
| af5c371e95 | |||
| 13c7f9a462 | |||
| 512e5e5bd1 | |||
| 7f782e4496 | |||
| c86b40f014 | |||
| 8ae45e7fe2 | |||
| 166ff0a093 | |||
| 82978fbd57 | |||
| 1186b3b67a | |||
| 30b948e68b | |||
| 1aa1461a2e | |||
| 92ae99bd29 | |||
| d4d33a4130 | |||
| 7a21c308be | |||
| 37cad52229 | |||
| 81315897f0 | |||
| 9254b6cf46 | |||
| 0e65fa85d3 | |||
| 4eb71ab555 | |||
| e9a64ef8a9 | |||
| a50d7f0f20 | |||
| 2903ffc54f | |||
| 5ea5310ab4 | |||
| 1256e4c645 | |||
| dc69d3e8d8 | |||
| 9c55ed0923 | |||
| 7c2c49d9b1 | |||
| 41bd2be68a | |||
| 66d7a4dcd8 | |||
| b9c026ce32 | |||
| c4457fba85 | |||
| d4b42995f7 | |||
| 485d57972e | |||
| 85c5a1ff8d | |||
| 7b8bb75228 | |||
| fe16457efc | |||
| 46533cac7d | |||
| 747a15841d | |||
| fc01f94387 | |||
| e9d4d17693 | |||
| 25f9c66834 | |||
| d25a3f13c2 | |||
| b13376e918 | |||
| c8b4ef7fed | |||
| b0f9f5ac21 | |||
| 6062f74c6b | |||
| eb365a01fb | |||
| eb0c88a9d4 | |||
| db3bffa284 | |||
| ca6c0de380 | |||
| d91ff81ca6 | |||
| 9d2140c9a1 | |||
| 7a0f454d39 | |||
| d5b717dc77 | |||
| 7cb517ce54 | |||
| a460404252 | |||
| d0287608b6 | |||
| 1532376710 | |||
| d3122db7b2 | |||
| b46b8933ab | |||
| 62f3e6db75 | |||
| a0c57b35a3 | |||
| 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 | |||
| 9f86454b48 | |||
| b852df020c | |||
| fa926fb47c | |||
| 6fc2c29daa | |||
| a1b31d93b6 | |||
| 824f8c45ed | |||
| a0822259e7 | |||
| 9b8283d0fc | |||
| 04a7674bdd | |||
| 2d4cfc58ec | |||
| 0dc4797a4c | |||
| b668db242d | |||
| bbfe6fa50b | |||
| a15108e65b | |||
| aa1083bdac | |||
| b3c720b1c3 | |||
| 657245dcbd | |||
| 5af2555f59 | |||
| 49882dc151 | |||
| 19438d3021 | |||
| d5c481c2f4 | |||
| 8763e4efde | |||
| ecb8c1389c | |||
| d4690a8fa1 | |||
| d05f5eeb1d | |||
| 4362417495 | |||
| a9bbe11169 | |||
| 45e60cb52a | |||
| 211068ce50 | |||
| 051f7fb28c | |||
| 79666a3046 | |||
| 78abff6a52 | |||
| 1daa8e4a0f | |||
| dc76489221 | |||
| 7c503c4438 | |||
| b83690ebd8 | |||
| a34d920847 | |||
| 358c689cec | |||
| 2e8625c25f | |||
| ab86a5124a | |||
| 280972a66c | |||
| 200c758ff4 | |||
| 8492f37323 | |||
| f8c3798522 | |||
| 9f3477a279 | |||
| 046b931624 | |||
| 70549136ba | |||
| 6c0c750000 | |||
| 2f3c05651e | |||
| fa9a7bbb3c | |||
| 830612f555 | |||
| d49446ff98 | |||
| dc59f164a9 | |||
| deab6280d3 | |||
| d07abb5c42 | |||
| fb9df0c269 | |||
| af8292c1de | |||
| 38cf3413df | |||
| 800868e27e | |||
| c70bfefc68 | |||
| 15317991f3 | |||
| 4188f38ad5 | |||
| 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 |
10
.editorconfig
Normal file
10
.editorconfig
Normal file
@ -0,0 +1,10 @@
|
||||
; top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
; Unix-style newlines
|
||||
[*]
|
||||
end_of_line = LF
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
44
.gitignore
vendored
44
.gitignore
vendored
@ -1,6 +1,38 @@
|
||||
assets/*
|
||||
cache/*
|
||||
vendor
|
||||
composer.phar
|
||||
db/poche.sqlite
|
||||
inc/poche/config.inc.php
|
||||
# Cache and logs (Symfony2)
|
||||
/app/cache/*
|
||||
/app/logs/*
|
||||
!app/cache/.gitkeep
|
||||
!app/logs/.gitkeep
|
||||
|
||||
# Cache and logs (Symfony3)
|
||||
/var/cache/*
|
||||
/var/logs/*
|
||||
!var/cache/.gitkeep
|
||||
!var/logs/.gitkeep
|
||||
|
||||
# Parameters
|
||||
/app/config/parameters.yml
|
||||
/app/config/parameters.ini
|
||||
|
||||
# Managed by Composer
|
||||
/app/bootstrap.php.cache
|
||||
/var/bootstrap.php.cache
|
||||
/bin/*
|
||||
!bin/console
|
||||
!bin/symfony_requirements
|
||||
/vendor/
|
||||
|
||||
# Assets and user uploads
|
||||
/web/bundles/
|
||||
/web/uploads/
|
||||
|
||||
# Build
|
||||
/app/build
|
||||
/build
|
||||
|
||||
# Composer PHAR
|
||||
/composer.phar
|
||||
|
||||
# Data for wallabag
|
||||
data/assets/*
|
||||
data/db/wallabag*.sqlite
|
||||
|
||||
27
.scrutinizer.yml
Normal file
27
.scrutinizer.yml
Normal file
@ -0,0 +1,27 @@
|
||||
filter:
|
||||
paths:
|
||||
- src/*
|
||||
excluded_paths:
|
||||
- 'vendor/*'
|
||||
- 'app/*'
|
||||
- 'web/*'
|
||||
- 'src/Wallabag/*Bundle/Tests/*'
|
||||
- '*Test.php'
|
||||
|
||||
tools:
|
||||
php_cs_fixer: true
|
||||
php_analyzer: true
|
||||
php_mess_detector: true
|
||||
php_changetracking: true
|
||||
php_code_sniffer: true
|
||||
php_pdepend: true
|
||||
sensiolabs_security_checker: true
|
||||
#external_code_coverage:
|
||||
# timeout: 3600
|
||||
php_code_coverage: true
|
||||
php_sim: false
|
||||
php_cpd: false
|
||||
|
||||
checks:
|
||||
php:
|
||||
code_rating: true
|
||||
45
.travis.yml
Normal file
45
.travis.yml
Normal file
@ -0,0 +1,45 @@
|
||||
language: php
|
||||
|
||||
# faster builds on docker-container setup
|
||||
sudo: false
|
||||
|
||||
# cache vendor dirs
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
- nightly
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
- php: nightly
|
||||
|
||||
branches:
|
||||
only:
|
||||
- v2
|
||||
|
||||
install:
|
||||
- composer self-update
|
||||
|
||||
# build coverage only on one build, to speed up results feedbacks
|
||||
# before_script:
|
||||
# - if [[ "$TRAVIS_PHP_VERSION" = "5.6" ]]; then PHPUNIT_FLAGS="--coverage-clover=coverage.clover"; else PHPUNIT_FLAGS=""; fi;
|
||||
|
||||
script:
|
||||
- ant prepare
|
||||
- bin/phpunit --exclude-group command-doctrine --debug $PHPUNIT_FLAGS
|
||||
|
||||
# after_script:
|
||||
# - |
|
||||
# if [ $TRAVIS_PHP_VERSION = '5.6' ]; then
|
||||
# wget https://scrutinizer-ci.com/ocular.phar
|
||||
# php ocular.phar code-coverage:upload --format=php-clover coverage.clover
|
||||
# fi
|
||||
@ -1,11 +1,30 @@
|
||||
# How contributing
|
||||
# How to contribute
|
||||
|
||||
## You found a bug
|
||||
Please [open a new issue](https://github.com/inthepoche/poche/issues/new).
|
||||
Please [open a new issue](https://github.com/wallabag/wallabag/issues/new).
|
||||
|
||||
To fix the bug quickly, we need some infos:
|
||||
* your poche version (in ./inc/poche/myconfig.inc.php)
|
||||
* the link you want to poche and which causes problem
|
||||
* your wallabag version (on top of the ./index.php file, and also on config page)
|
||||
* your webserver installation :
|
||||
* type of hosting (shared or dedicated)
|
||||
* in case of a dedicated 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 poche and work with **the dev branch** only. Do not work on master branch.
|
||||
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).
|
||||
|
||||
27
COPYING.md
27
COPYING.md
@ -1,14 +1,19 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
Copyright (c) 2013-2015 Nicolas Lœuillet
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
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:
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
17
CREDITS.md
17
CREDITS.md
@ -1,15 +1,6 @@
|
||||
poche is based on :
|
||||
* PHP Readability https://bitbucket.org/fivefilters/php-readability
|
||||
* Full Text RSS http://code.fivefilters.org/full-text-rss/src
|
||||
* 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
|
||||
* Twig http://twig.sensiolabs.org
|
||||
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
|
||||
* Pagination https://github.com/daveismyname/pagination
|
||||
wallabag is mainly developed by [Nicolas Lœuillet](https://github.com/nicosomb) under the MIT License.
|
||||
|
||||
poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
|
||||
Thank you so much to [@tcitworld](https://github.com/tcitworld) and [@j0k3r](https://github.com/j0k3r).
|
||||
|
||||
Contributors : https://github.com/inthepoche/poche/graphs/contributors
|
||||
Thank you [to others contributors](https://github.com/wallabag/wallabag/graphs/contributors
|
||||
).
|
||||
|
||||
29
Capfile
Normal file
29
Capfile
Normal file
@ -0,0 +1,29 @@
|
||||
# Load DSL and set up stages
|
||||
require 'capistrano/setup'
|
||||
|
||||
# Include default deployment tasks
|
||||
require 'capistrano/deploy'
|
||||
|
||||
require 'capistrano/symfony'
|
||||
|
||||
# Include tasks from other gems included in your Gemfile
|
||||
#
|
||||
# For documentation on these, see for example:
|
||||
#
|
||||
# https://github.com/capistrano/rvm
|
||||
# https://github.com/capistrano/rbenv
|
||||
# https://github.com/capistrano/chruby
|
||||
# https://github.com/capistrano/bundler
|
||||
# https://github.com/capistrano/rails
|
||||
# https://github.com/capistrano/passenger
|
||||
#
|
||||
# require 'capistrano/rvm'
|
||||
# require 'capistrano/rbenv'
|
||||
# require 'capistrano/chruby'
|
||||
# require 'capistrano/bundler'
|
||||
# require 'capistrano/rails/assets'
|
||||
# require 'capistrano/rails/migrations'
|
||||
# require 'capistrano/passenger'
|
||||
|
||||
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
|
||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||
53
GUIDELINES.md
Normal file
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/).
|
||||
5
Gemfile
Normal file
5
Gemfile
Normal file
@ -0,0 +1,5 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem 'capistrano', '~> 3.1'
|
||||
gem 'capistrano-symfony', '~> 0.1', :github => 'capistrano/symfony'
|
||||
gem 'capistrano-composer', '~> 0.0.3'
|
||||
41
Gemfile.lock
Normal file
41
Gemfile.lock
Normal file
@ -0,0 +1,41 @@
|
||||
GIT
|
||||
remote: git://github.com/capistrano/symfony.git
|
||||
revision: ca56a01b817097d2831400ef9b1867fc8e07dcf8
|
||||
specs:
|
||||
capistrano-symfony (0.4.0)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-composer (~> 0.0.3)
|
||||
capistrano-file-permissions (~> 0.1.0)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
capistrano (3.4.0)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (~> 1.3)
|
||||
capistrano-composer (0.0.6)
|
||||
capistrano (>= 3.0.0.pre)
|
||||
capistrano-file-permissions (0.1.1)
|
||||
capistrano (~> 3.1)
|
||||
colorize (0.7.7)
|
||||
i18n (0.7.0)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.9.2)
|
||||
rake (10.4.2)
|
||||
sshkit (1.7.1)
|
||||
colorize (>= 0.7.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
capistrano (~> 3.1)
|
||||
capistrano-composer (~> 0.0.3)
|
||||
capistrano-symfony (~> 0.1)!
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.6
|
||||
72
INSTALL.md
72
INSTALL.md
@ -1,72 +0,0 @@
|
||||
# Installing poche
|
||||
|
||||
## requirements
|
||||
* PHP 5.2.0 or higher
|
||||
* XML ([?](http://php.net/xml))
|
||||
* PCRE ([?](http://php.net/pcre))
|
||||
* Data filtering ([?](http://uk.php.net/manual/en/book.filter.php))
|
||||
* Tidy ([?](http://php.net/tidy))
|
||||
* cURL ([?](http://php.net/curl))
|
||||
* Parallel URL fetching
|
||||
* allow_url_fopen ([?](http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen))
|
||||
|
||||
To see if your server is ok to run poche, execute http://yourpoche/poche_compatibility_test.php.
|
||||
|
||||
## you don't want to install twig (the template engine) by yourself
|
||||
|
||||
Download this file http://static.inthepoche.com/files/poche-1.0-latest-with-twig.zip
|
||||
|
||||
Extract this file on your server.
|
||||
|
||||
## you want to install twig by yourself
|
||||
|
||||
Download the latest version here : http://www.inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche
|
||||
|
||||
Extract this file on your server.
|
||||
|
||||
```php
|
||||
curl -s http://getcomposer.org/installer | php
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
### using sqlite
|
||||
|
||||
Copy / paste install/poche.sqlite in db folder.
|
||||
|
||||
### using mysql or postgresql
|
||||
|
||||
Execute the sql file in /install (mysql.sql or postgres.sql)
|
||||
|
||||
Then, go to step 3.
|
||||
|
||||
# Upgrading poche
|
||||
|
||||
Replace all the files except **db/poche.sqlite**. Also remember to edit the file /inc/poche/config.inc.php.
|
||||
|
||||
## Upgrading from poche <= 0.3
|
||||
|
||||
You have to execute http://yourpoche/install/update_sqlite_from_0_to_1.php
|
||||
|
||||
Then, go to step 3.
|
||||
|
||||
## Upgrading from poche >= 1.0 beta1
|
||||
|
||||
Nothing to do here.
|
||||
|
||||
Then, go to step 3.
|
||||
|
||||
# Here is the step 3
|
||||
|
||||
You must have write access on assets, cache and db directories. These directories may not exist, you'll have to create them.
|
||||
|
||||
You can use poche ! Enjoy.
|
||||
|
||||
# Some problems you may encounter
|
||||
|
||||
## Blank page
|
||||
|
||||
Be sure to have write access on assets, cache and db directories.
|
||||
|
||||
## PHP Fatal error: Call to a member function fetchAll() on a non-object in /var/www/poche/inc/poche/Database.class.php on line 42
|
||||
|
||||
If you want to install poche, delete the db/poche.sqlite file and copy / paste the install/poche.sqlite in /db. Be sure to have write access.
|
||||
41
README.md
41
README.md
@ -1,29 +1,26 @@
|
||||
# what is poche ?
|
||||
Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is free (like in freedom) and open source.
|
||||
[](https://travis-ci.org/wallabag/wallabag)
|
||||
[](https://scrutinizer-ci.com/g/wallabag/wallabag/?branch=v2)
|
||||
[](https://scrutinizer-ci.com/g/wallabag/wallabag/?branch=v2)
|
||||
|
||||
## Some features
|
||||
* adding, deleting, archiving and setting as favorite a link
|
||||
* import from pocket / readability / instapaper
|
||||
* share links by email and on twitter
|
||||
* a design adapted to tablets and smartphones
|
||||
* extensions for Chrome and Firefox
|
||||
* Android application
|
||||
* multi languages: french, english, spanish, german.
|
||||
* multi users (very soon!)
|
||||
* update notification in configuration screen
|
||||
* many storage modes (sqlite, mysql, postgresql)
|
||||
* many templates: [have a look here](https://github.com/inthepoche/poche/tree/master/themes).
|
||||
* ...
|
||||
# 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.
|
||||
|
||||
To test poche, a demo website is online : [demo.inthepoche.com](http://demo.inthepoche.com) (login poche, password poche).
|
||||
More informations on our website: [wallabag.org](http://wallabag.org)
|
||||
|
||||
To use poche hosting, [you can create an account here](http://app.inthepoche.com/).
|
||||
# Want to test the v2 ?
|
||||
|
||||
## Installation
|
||||
Read the [INSTALL.md file](https://github.com/inthepoche/poche/blob/master/INSTALL.md).
|
||||
Keep in mind it's an **instable** branch, everything can be broken :)
|
||||
|
||||
```
|
||||
git clone https://github.com/wallabag/wallabag.git -b v2
|
||||
cd wallabag
|
||||
composer install
|
||||
php app/console wallabag:install
|
||||
php app/console server:run
|
||||
```
|
||||
|
||||
## License
|
||||
Copyright © 2010-2013 Nicolas Lœuillet <nicolas.loeuillet@gmail.com>
|
||||
Copyright © 2013-2015 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.
|
||||
|
||||
9
TODO.md
9
TODO.md
@ -1,9 +0,0 @@
|
||||
# TODO
|
||||
|
||||
* pouvoir annuler la suppression
|
||||
* conventions codage ? phing ? vérifier error_log qui trainent
|
||||
* phpDocumentor
|
||||
* minifier css
|
||||
* barre fixe d'admin sur la page d'un billet ?
|
||||
* revoir export (export vers pocket &cie ? )
|
||||
* raccourcis clavier
|
||||
67
TRANSLATION.md
Normal file
67
TRANSLATION.md
Normal 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
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
|
||||
7
app/.htaccess
Normal file
7
app/.htaccess
Normal file
@ -0,0 +1,7 @@
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
9
app/AppCache.php
Normal file
9
app/AppCache.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/AppKernel.php';
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
|
||||
|
||||
class AppCache extends HttpCache
|
||||
{
|
||||
}
|
||||
46
app/AppKernel.php
Normal file
46
app/AppKernel.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
|
||||
class AppKernel extends Kernel
|
||||
{
|
||||
public function registerBundles()
|
||||
{
|
||||
$bundles = array(
|
||||
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
|
||||
new Symfony\Bundle\TwigBundle\TwigBundle(),
|
||||
new Symfony\Bundle\MonologBundle\MonologBundle(),
|
||||
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
|
||||
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
|
||||
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
|
||||
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
|
||||
new FOS\RestBundle\FOSRestBundle(),
|
||||
new FOS\UserBundle\FOSUserBundle(),
|
||||
new JMS\SerializerBundle\JMSSerializerBundle(),
|
||||
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
|
||||
new Nelmio\CorsBundle\NelmioCorsBundle(),
|
||||
new Liip\ThemeBundle\LiipThemeBundle(),
|
||||
new Wallabag\CoreBundle\WallabagCoreBundle(),
|
||||
new Wallabag\ApiBundle\WallabagApiBundle(),
|
||||
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
|
||||
new Lexik\Bundle\FormFilterBundle\LexikFormFilterBundle(),
|
||||
);
|
||||
|
||||
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
|
||||
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
|
||||
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
|
||||
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
|
||||
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
|
||||
$bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
|
||||
}
|
||||
|
||||
return $bundles;
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
|
||||
}
|
||||
}
|
||||
0
assets/.gitignore → app/Resources/views/.gitkeep
Executable file → Normal file
0
assets/.gitignore → app/Resources/views/.gitkeep
Executable file → Normal file
758
app/SymfonyRequirements.php
Normal file
758
app/SymfonyRequirements.php
Normal file
@ -0,0 +1,758 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Users of PHP 5.2 should be able to run the requirements checks.
|
||||
* This is why the file and all classes must be compatible with PHP 5.2+
|
||||
* (e.g. not using namespaces and closures).
|
||||
*
|
||||
* ************** CAUTION **************
|
||||
*
|
||||
* DO NOT EDIT THIS FILE as it will be overridden by Composer as part of
|
||||
* the installation/update process. The original file resides in the
|
||||
* SensioDistributionBundle.
|
||||
*
|
||||
* ************** CAUTION **************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a single PHP requirement, e.g. an installed extension.
|
||||
* It can be a mandatory requirement or an optional recommendation.
|
||||
* There is a special subclass, named PhpIniRequirement, to check a php.ini configuration.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class Requirement
|
||||
{
|
||||
private $fulfilled;
|
||||
private $testMessage;
|
||||
private $helpText;
|
||||
private $helpHtml;
|
||||
private $optional;
|
||||
|
||||
/**
|
||||
* Constructor that initializes the requirement.
|
||||
*
|
||||
* @param bool $fulfilled Whether the requirement is fulfilled
|
||||
* @param string $testMessage The message for testing the requirement
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
|
||||
*/
|
||||
public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
|
||||
{
|
||||
$this->fulfilled = (bool) $fulfilled;
|
||||
$this->testMessage = (string) $testMessage;
|
||||
$this->helpHtml = (string) $helpHtml;
|
||||
$this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
|
||||
$this->optional = (bool) $optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the requirement is fulfilled.
|
||||
*
|
||||
* @return bool true if fulfilled, otherwise false
|
||||
*/
|
||||
public function isFulfilled()
|
||||
{
|
||||
return $this->fulfilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message for testing the requirement.
|
||||
*
|
||||
* @return string The test message
|
||||
*/
|
||||
public function getTestMessage()
|
||||
{
|
||||
return $this->testMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the help text for resolving the problem.
|
||||
*
|
||||
* @return string The help text
|
||||
*/
|
||||
public function getHelpText()
|
||||
{
|
||||
return $this->helpText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the help text formatted in HTML.
|
||||
*
|
||||
* @return string The HTML help
|
||||
*/
|
||||
public function getHelpHtml()
|
||||
{
|
||||
return $this->helpHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is only an optional recommendation and not a mandatory requirement.
|
||||
*
|
||||
* @return bool true if optional, false if mandatory
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return $this->optional;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a PHP requirement in form of a php.ini configuration.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class PhpIniRequirement extends Requirement
|
||||
{
|
||||
/**
|
||||
* Constructor that initializes the requirement.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
|
||||
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
|
||||
* @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
|
||||
*/
|
||||
public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
|
||||
{
|
||||
$cfgValue = ini_get($cfgName);
|
||||
|
||||
if (is_callable($evaluation)) {
|
||||
if (null === $testMessage || null === $helpHtml) {
|
||||
throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.');
|
||||
}
|
||||
|
||||
$fulfilled = call_user_func($evaluation, $cfgValue);
|
||||
} else {
|
||||
if (null === $testMessage) {
|
||||
$testMessage = sprintf('%s %s be %s in php.ini',
|
||||
$cfgName,
|
||||
$optional ? 'should' : 'must',
|
||||
$evaluation ? 'enabled' : 'disabled'
|
||||
);
|
||||
}
|
||||
|
||||
if (null === $helpHtml) {
|
||||
$helpHtml = sprintf('Set <strong>%s</strong> to <strong>%s</strong> in php.ini<a href="#phpini">*</a>.',
|
||||
$cfgName,
|
||||
$evaluation ? 'on' : 'off'
|
||||
);
|
||||
}
|
||||
|
||||
$fulfilled = $evaluation == $cfgValue;
|
||||
}
|
||||
|
||||
parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A RequirementCollection represents a set of Requirement instances.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class RequirementCollection implements IteratorAggregate
|
||||
{
|
||||
private $requirements = array();
|
||||
|
||||
/**
|
||||
* Gets the current RequirementCollection as an Iterator.
|
||||
*
|
||||
* @return Traversable A Traversable interface
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->requirements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Requirement.
|
||||
*
|
||||
* @param Requirement $requirement A Requirement instance
|
||||
*/
|
||||
public function add(Requirement $requirement)
|
||||
{
|
||||
$this->requirements[] = $requirement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mandatory requirement.
|
||||
*
|
||||
* @param bool $fulfilled Whether the requirement is fulfilled
|
||||
* @param string $testMessage The message for testing the requirement
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null)
|
||||
{
|
||||
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an optional recommendation.
|
||||
*
|
||||
* @param bool $fulfilled Whether the recommendation is fulfilled
|
||||
* @param string $testMessage The message for testing the recommendation
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null)
|
||||
{
|
||||
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mandatory requirement in form of a php.ini configuration.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
|
||||
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
|
||||
{
|
||||
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an optional recommendation in form of a php.ini configuration.
|
||||
*
|
||||
* @param string $cfgName The configuration name used for ini_get()
|
||||
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
|
||||
* or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
|
||||
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
|
||||
* This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
|
||||
* Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
|
||||
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
|
||||
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
|
||||
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
|
||||
*/
|
||||
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
|
||||
{
|
||||
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a requirement collection to the current set of requirements.
|
||||
*
|
||||
* @param RequirementCollection $collection A RequirementCollection instance
|
||||
*/
|
||||
public function addCollection(RequirementCollection $collection)
|
||||
{
|
||||
$this->requirements = array_merge($this->requirements, $collection->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns both requirements and recommendations.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all mandatory requirements.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getRequirements()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mandatory requirements that were not met.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getFailedRequirements()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && !$req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all optional recommendations.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getRecommendations()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if ($req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the recommendations that were not met.
|
||||
*
|
||||
* @return array Array of Requirement instances
|
||||
*/
|
||||
public function getFailedRecommendations()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && $req->isOptional()) {
|
||||
$array[] = $req;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a php.ini configuration is not correct.
|
||||
*
|
||||
* @return bool php.ini configuration problem?
|
||||
*/
|
||||
public function hasPhpIniConfigIssue()
|
||||
{
|
||||
foreach ($this->requirements as $req) {
|
||||
if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PHP configuration file (php.ini) path.
|
||||
*
|
||||
* @return string|false php.ini file path
|
||||
*/
|
||||
public function getPhpIniConfigPath()
|
||||
{
|
||||
return get_cfg_var('cfg_file_path');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class specifies all requirements and optional recommendations that
|
||||
* are necessary to run the Symfony Standard Edition.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class SymfonyRequirements extends RequirementCollection
|
||||
{
|
||||
const REQUIRED_PHP_VERSION = '5.3.3';
|
||||
|
||||
/**
|
||||
* Constructor that initializes the requirements.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/* mandatory requirements follow */
|
||||
|
||||
$installedPhpVersion = phpversion();
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='),
|
||||
sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion),
|
||||
sprintf('You are running PHP version "<strong>%s</strong>", but Symfony needs at least PHP "<strong>%s</strong>" to run.
|
||||
Before using Symfony, upgrade your PHP installation, preferably to the latest version.',
|
||||
$installedPhpVersion, self::REQUIRED_PHP_VERSION),
|
||||
sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion)
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
version_compare($installedPhpVersion, '5.3.16', '!='),
|
||||
'PHP version must not be 5.3.16 as Symfony won\'t work properly with it',
|
||||
'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
is_dir(__DIR__.'/../vendor/composer'),
|
||||
'Vendor libraries must be installed',
|
||||
'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. '.
|
||||
'Then run "<strong>php composer.phar install</strong>" to install them.'
|
||||
);
|
||||
|
||||
$cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache';
|
||||
|
||||
$this->addRequirement(
|
||||
is_writable($cacheDir),
|
||||
'app/cache/ or var/cache/ directory must be writable',
|
||||
'Change the permissions of either "<strong>app/cache/</strong>" or "<strong>var/cache/</strong>" directory so that the web server can write into it.'
|
||||
);
|
||||
|
||||
$logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs';
|
||||
|
||||
$this->addRequirement(
|
||||
is_writable($logsDir),
|
||||
'app/logs/ or var/logs/ directory must be writable',
|
||||
'Change the permissions of either "<strong>app/logs/</strong>" or "<strong>var/logs/</strong>" directory so that the web server can write into it.'
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'date.timezone', true, false,
|
||||
'date.timezone setting must be set',
|
||||
'Set the "<strong>date.timezone</strong>" setting in php.ini<a href="#phpini">*</a> (like Europe/Paris).'
|
||||
);
|
||||
|
||||
if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
|
||||
$timezones = array();
|
||||
foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
|
||||
foreach ($abbreviations as $abbreviation) {
|
||||
$timezones[$abbreviation['timezone_id']] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
isset($timezones[@date_default_timezone_get()]),
|
||||
sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
|
||||
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('json_encode'),
|
||||
'json_encode() must be available',
|
||||
'Install and enable the <strong>JSON</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('session_start'),
|
||||
'session_start() must be available',
|
||||
'Install and enable the <strong>session</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('ctype_alpha'),
|
||||
'ctype_alpha() must be available',
|
||||
'Install and enable the <strong>ctype</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('token_get_all'),
|
||||
'token_get_all() must be available',
|
||||
'Install and enable the <strong>Tokenizer</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRequirement(
|
||||
function_exists('simplexml_import_dom'),
|
||||
'simplexml_import_dom() must be available',
|
||||
'Install and enable the <strong>SimpleXML</strong> extension.'
|
||||
);
|
||||
|
||||
if (function_exists('apc_store') && ini_get('apc.enabled')) {
|
||||
if (version_compare($installedPhpVersion, '5.4.0', '>=')) {
|
||||
$this->addRequirement(
|
||||
version_compare(phpversion('apc'), '3.1.13', '>='),
|
||||
'APC version must be at least 3.1.13 when using PHP 5.4',
|
||||
'Upgrade your <strong>APC</strong> extension (3.1.13+).'
|
||||
);
|
||||
} else {
|
||||
$this->addRequirement(
|
||||
version_compare(phpversion('apc'), '3.0.17', '>='),
|
||||
'APC version must be at least 3.0.17',
|
||||
'Upgrade your <strong>APC</strong> extension (3.0.17+).'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addPhpIniRequirement('detect_unicode', false);
|
||||
|
||||
if (extension_loaded('suhosin')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'suhosin.executor.include.whitelist',
|
||||
create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
|
||||
false,
|
||||
'suhosin.executor.include.whitelist must be configured correctly in php.ini',
|
||||
'Add "<strong>phar</strong>" to <strong>suhosin.executor.include.whitelist</strong> in php.ini<a href="#phpini">*</a>.'
|
||||
);
|
||||
}
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.show_exception_trace', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRequirement(
|
||||
'xdebug.scream', false, true
|
||||
);
|
||||
|
||||
$this->addPhpIniRecommendation(
|
||||
'xdebug.max_nesting_level',
|
||||
create_function('$cfgValue', 'return $cfgValue > 100;'),
|
||||
true,
|
||||
'xdebug.max_nesting_level should be above 100 in php.ini',
|
||||
'Set "<strong>xdebug.max_nesting_level</strong>" to e.g. "<strong>250</strong>" in php.ini<a href="#phpini">*</a> to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
|
||||
);
|
||||
}
|
||||
|
||||
$pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null;
|
||||
|
||||
$this->addRequirement(
|
||||
null !== $pcreVersion,
|
||||
'PCRE extension must be available',
|
||||
'Install the <strong>PCRE</strong> extension (version 8.0+).'
|
||||
);
|
||||
|
||||
if (extension_loaded('mbstring')) {
|
||||
$this->addPhpIniRequirement(
|
||||
'mbstring.func_overload',
|
||||
create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
|
||||
true,
|
||||
'string functions should not be overloaded',
|
||||
'Set "<strong>mbstring.func_overload</strong>" to <strong>0</strong> in php.ini<a href="#phpini">*</a> to disable function overloading by the mbstring extension.'
|
||||
);
|
||||
}
|
||||
|
||||
/* optional recommendations follow */
|
||||
|
||||
if (file_exists(__DIR__.'/../vendor/composer')) {
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
try {
|
||||
$r = new \ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle');
|
||||
|
||||
$contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php');
|
||||
} catch (\ReflectionException $e) {
|
||||
$contents = '';
|
||||
}
|
||||
$this->addRecommendation(
|
||||
file_get_contents(__FILE__) === $contents,
|
||||
'Requirements file should be up-to-date',
|
||||
'Your requirements file is outdated. Run composer install and re-check your configuration.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.3.4', '>='),
|
||||
'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions',
|
||||
'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.3.8', '>='),
|
||||
'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
|
||||
'Install PHP 5.3.8 or newer if your project uses annotations.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.4.0', '!='),
|
||||
'You should not use PHP 5.4.0 due to the PHP bug #61453',
|
||||
'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($installedPhpVersion, '5.4.11', '>='),
|
||||
'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)',
|
||||
'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
(version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<'))
|
||||
||
|
||||
version_compare($installedPhpVersion, '5.4.8', '>='),
|
||||
'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909',
|
||||
'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.'
|
||||
);
|
||||
|
||||
if (null !== $pcreVersion) {
|
||||
$this->addRecommendation(
|
||||
$pcreVersion >= 8.0,
|
||||
sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion),
|
||||
'<strong>PCRE 8.0+</strong> is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
class_exists('DomDocument'),
|
||||
'PHP-DOM and PHP-XML modules should be installed',
|
||||
'Install and enable the <strong>PHP-DOM</strong> and the <strong>PHP-XML</strong> modules.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('mb_strlen'),
|
||||
'mb_strlen() should be available',
|
||||
'Install and enable the <strong>mbstring</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('iconv'),
|
||||
'iconv() should be available',
|
||||
'Install and enable the <strong>iconv</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('utf8_decode'),
|
||||
'utf8_decode() should be available',
|
||||
'Install and enable the <strong>XML</strong> extension.'
|
||||
);
|
||||
|
||||
$this->addRecommendation(
|
||||
function_exists('filter_var'),
|
||||
'filter_var() should be available',
|
||||
'Install and enable the <strong>filter</strong> extension.'
|
||||
);
|
||||
|
||||
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->addRecommendation(
|
||||
function_exists('posix_isatty'),
|
||||
'posix_isatty() should be available',
|
||||
'Install and enable the <strong>php_posix</strong> extension (used to colorize the CLI output).'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
extension_loaded('intl'),
|
||||
'intl extension should be available',
|
||||
'Install and enable the <strong>intl</strong> extension (used for validators).'
|
||||
);
|
||||
|
||||
if (extension_loaded('intl')) {
|
||||
// in some WAMP server installations, new Collator() returns null
|
||||
$this->addRecommendation(
|
||||
null !== new Collator('fr_FR'),
|
||||
'intl extension should be correctly configured',
|
||||
'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.'
|
||||
);
|
||||
|
||||
// check for compatible ICU versions (only done when you have the intl extension)
|
||||
if (defined('INTL_ICU_VERSION')) {
|
||||
$version = INTL_ICU_VERSION;
|
||||
} else {
|
||||
$reflector = new ReflectionExtension('intl');
|
||||
|
||||
ob_start();
|
||||
$reflector->info();
|
||||
$output = strip_tags(ob_get_clean());
|
||||
|
||||
preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches);
|
||||
$version = $matches[1];
|
||||
}
|
||||
|
||||
$this->addRecommendation(
|
||||
version_compare($version, '4.0', '>='),
|
||||
'intl ICU version should be at least 4+',
|
||||
'Upgrade your <strong>intl</strong> extension with a newer ICU version (4+).'
|
||||
);
|
||||
|
||||
$this->addPhpIniRecommendation(
|
||||
'intl.error_level',
|
||||
create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
|
||||
true,
|
||||
'intl.error_level should be 0 in php.ini',
|
||||
'Set "<strong>intl.error_level</strong>" to "<strong>0</strong>" in php.ini<a href="#phpini">*</a> to inhibit the messages when an error occurs in ICU functions.'
|
||||
);
|
||||
}
|
||||
|
||||
$accelerator =
|
||||
(extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'))
|
||||
||
|
||||
(extension_loaded('apc') && ini_get('apc.enabled'))
|
||||
||
|
||||
(extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable'))
|
||||
||
|
||||
(extension_loaded('Zend OPcache') && ini_get('opcache.enable'))
|
||||
||
|
||||
(extension_loaded('xcache') && ini_get('xcache.cacher'))
|
||||
||
|
||||
(extension_loaded('wincache') && ini_get('wincache.ocenabled'))
|
||||
;
|
||||
|
||||
$this->addRecommendation(
|
||||
$accelerator,
|
||||
'a PHP accelerator should be installed',
|
||||
'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
|
||||
);
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
$this->addRecommendation(
|
||||
$this->getRealpathCacheSize() > 1000,
|
||||
'realpath_cache_size should be above 1024 in php.ini',
|
||||
'Set "<strong>realpath_cache_size</strong>" to e.g. "<strong>1024</strong>" in php.ini<a href="#phpini">*</a> to improve performance on windows.'
|
||||
);
|
||||
}
|
||||
|
||||
$this->addPhpIniRecommendation('short_open_tag', false);
|
||||
|
||||
$this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
|
||||
|
||||
$this->addPhpIniRecommendation('register_globals', false, true);
|
||||
|
||||
$this->addPhpIniRecommendation('session.auto_start', false);
|
||||
|
||||
$this->addRecommendation(
|
||||
class_exists('PDO'),
|
||||
'PDO should be installed',
|
||||
'Install <strong>PDO</strong> (mandatory for Doctrine).'
|
||||
);
|
||||
|
||||
if (class_exists('PDO')) {
|
||||
$drivers = PDO::getAvailableDrivers();
|
||||
$this->addRecommendation(
|
||||
count($drivers) > 0,
|
||||
sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
|
||||
'Install <strong>PDO drivers</strong> (mandatory for Doctrine).'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads realpath_cache_size from php.ini and converts it to int.
|
||||
*
|
||||
* (e.g. 16k is converted to 16384 int)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getRealpathCacheSize()
|
||||
{
|
||||
$size = ini_get('realpath_cache_size');
|
||||
$size = trim($size);
|
||||
$unit = strtolower(substr($size, -1, 1));
|
||||
switch ($unit) {
|
||||
case 'g':
|
||||
return $size * 1024 * 1024 * 1024;
|
||||
case 'm':
|
||||
return $size * 1024 * 1024;
|
||||
case 'k':
|
||||
return $size * 1024;
|
||||
default:
|
||||
return (int) $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
app/autoload.php
Normal file
13
app/autoload.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use Composer\Autoload\ClassLoader;
|
||||
|
||||
/**
|
||||
* @var ClassLoader $loader
|
||||
*/
|
||||
$loader = require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
|
||||
|
||||
return $loader;
|
||||
142
app/check.php
Normal file
142
app/check.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(__FILE__).'/SymfonyRequirements.php';
|
||||
|
||||
$lineSize = 70;
|
||||
$symfonyRequirements = new SymfonyRequirements();
|
||||
$iniPath = $symfonyRequirements->getPhpIniConfigPath();
|
||||
|
||||
echo_title('Symfony2 Requirements Checker');
|
||||
|
||||
echo '> PHP is using the following php.ini file:'.PHP_EOL;
|
||||
if ($iniPath) {
|
||||
echo_style('green', ' '.$iniPath);
|
||||
} else {
|
||||
echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!');
|
||||
}
|
||||
|
||||
echo PHP_EOL.PHP_EOL;
|
||||
|
||||
echo '> Checking Symfony requirements:'.PHP_EOL.' ';
|
||||
|
||||
$messages = array();
|
||||
foreach ($symfonyRequirements->getRequirements() as $req) {
|
||||
/** @var $req Requirement */
|
||||
if ($helpText = get_error_message($req, $lineSize)) {
|
||||
echo_style('red', 'E');
|
||||
$messages['error'][] = $helpText;
|
||||
} else {
|
||||
echo_style('green', '.');
|
||||
}
|
||||
}
|
||||
|
||||
$checkPassed = empty($messages['error']);
|
||||
|
||||
foreach ($symfonyRequirements->getRecommendations() as $req) {
|
||||
if ($helpText = get_error_message($req, $lineSize)) {
|
||||
echo_style('yellow', 'W');
|
||||
$messages['warning'][] = $helpText;
|
||||
} else {
|
||||
echo_style('green', '.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($checkPassed) {
|
||||
echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects');
|
||||
} else {
|
||||
echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects');
|
||||
|
||||
echo_title('Fix the following mandatory requirements', 'red');
|
||||
|
||||
foreach ($messages['error'] as $helpText) {
|
||||
echo ' * '.$helpText.PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($messages['warning'])) {
|
||||
echo_title('Optional recommendations to improve your setup', 'yellow');
|
||||
|
||||
foreach ($messages['warning'] as $helpText) {
|
||||
echo ' * '.$helpText.PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
echo_style('title', 'Note');
|
||||
echo ' The command console could use a different php.ini file'.PHP_EOL;
|
||||
echo_style('title', '~~~~');
|
||||
echo ' than the one used with your web server. To be on the'.PHP_EOL;
|
||||
echo ' safe side, please check the requirements from your web'.PHP_EOL;
|
||||
echo ' server using the ';
|
||||
echo_style('yellow', 'web/config.php');
|
||||
echo ' script.'.PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
|
||||
exit($checkPassed ? 0 : 1);
|
||||
|
||||
function get_error_message(Requirement $requirement, $lineSize)
|
||||
{
|
||||
if ($requirement->isFulfilled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL;
|
||||
$errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL;
|
||||
|
||||
return $errorMessage;
|
||||
}
|
||||
|
||||
function echo_title($title, $style = null)
|
||||
{
|
||||
$style = $style ?: 'title';
|
||||
|
||||
echo PHP_EOL;
|
||||
echo_style($style, $title.PHP_EOL);
|
||||
echo_style($style, str_repeat('~', strlen($title)).PHP_EOL);
|
||||
echo PHP_EOL;
|
||||
}
|
||||
|
||||
function echo_style($style, $message)
|
||||
{
|
||||
// ANSI color codes
|
||||
$styles = array(
|
||||
'reset' => "\033[0m",
|
||||
'red' => "\033[31m",
|
||||
'green' => "\033[32m",
|
||||
'yellow' => "\033[33m",
|
||||
'error' => "\033[37;41m",
|
||||
'success' => "\033[37;42m",
|
||||
'title' => "\033[34m",
|
||||
);
|
||||
$supports = has_color_support();
|
||||
|
||||
echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : '');
|
||||
}
|
||||
|
||||
function echo_block($style, $title, $message)
|
||||
{
|
||||
$message = ' '.trim($message).' ';
|
||||
$width = strlen($message);
|
||||
|
||||
echo PHP_EOL.PHP_EOL;
|
||||
|
||||
echo_style($style, str_repeat(' ', $width).PHP_EOL);
|
||||
echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL);
|
||||
echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL);
|
||||
echo_style($style, str_repeat(' ', $width).PHP_EOL);
|
||||
}
|
||||
|
||||
function has_color_support()
|
||||
{
|
||||
static $support;
|
||||
|
||||
if (null === $support) {
|
||||
if (DIRECTORY_SEPARATOR == '\\') {
|
||||
$support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
|
||||
} else {
|
||||
$support = function_exists('posix_isatty') && @posix_isatty(STDOUT);
|
||||
}
|
||||
}
|
||||
|
||||
return $support;
|
||||
}
|
||||
159
app/config/config.yml
Normal file
159
app/config/config.yml
Normal file
@ -0,0 +1,159 @@
|
||||
imports:
|
||||
- { resource: parameters.yml }
|
||||
- { resource: security.yml }
|
||||
- { resource: services.yml }
|
||||
|
||||
framework:
|
||||
#esi: ~
|
||||
translator: { fallback: "%locale%" }
|
||||
secret: "%secret%"
|
||||
router:
|
||||
resource: "%kernel.root_dir%/config/routing.yml"
|
||||
strict_requirements: ~
|
||||
form: ~
|
||||
csrf_protection: ~
|
||||
validation: { enable_annotations: true }
|
||||
templating:
|
||||
engines: ['twig']
|
||||
#assets_version: SomeVersionScheme
|
||||
default_locale: "%locale%"
|
||||
trusted_hosts: ~
|
||||
trusted_proxies: ~
|
||||
session:
|
||||
# handler_id set to null will use default session handler from php.ini
|
||||
handler_id: ~
|
||||
fragments: ~
|
||||
http_method_override: true
|
||||
|
||||
# Twig Configuration
|
||||
twig:
|
||||
debug: "%kernel.debug%"
|
||||
strict_variables: "%kernel.debug%"
|
||||
globals:
|
||||
share_twitter: %share_twitter%
|
||||
share_mail: %share_mail%
|
||||
share_shaarli: %share_shaarli%
|
||||
shaarli_url: %shaarli_url%
|
||||
share_diaspora: %share_diaspora%
|
||||
diaspora_url: %diaspora_url%
|
||||
flattr: %flattr%
|
||||
flattrable: 1
|
||||
flattred: 2
|
||||
carrot: %carrot%
|
||||
show_printlink: %show_printlink%
|
||||
export_epub: %export_epub%
|
||||
export_mobi: %export_mobi%
|
||||
export_pdf: %export_pdf%
|
||||
version: %app.version%
|
||||
warning_message: %warning_message%
|
||||
paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb"
|
||||
flattr_url: "https://flattr.com/thing/1265480"
|
||||
form:
|
||||
resources:
|
||||
- LexikFormFilterBundle:Form:form_div_layout.html.twig
|
||||
|
||||
# Assetic Configuration
|
||||
assetic:
|
||||
debug: "%kernel.debug%"
|
||||
use_controller: false
|
||||
bundles: [ ]
|
||||
#java: /usr/bin/java
|
||||
filters:
|
||||
cssrewrite: ~
|
||||
#closure:
|
||||
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
|
||||
#yui_css:
|
||||
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
|
||||
|
||||
# Doctrine Configuration
|
||||
doctrine:
|
||||
dbal:
|
||||
driver: "%database_driver%"
|
||||
host: "%database_host%"
|
||||
port: "%database_port%"
|
||||
dbname: "%database_name%"
|
||||
user: "%database_user%"
|
||||
password: "%database_password%"
|
||||
charset: UTF8
|
||||
path: "%database_path%"
|
||||
|
||||
orm:
|
||||
auto_generate_proxy_classes: "%kernel.debug%"
|
||||
entity_managers:
|
||||
default:
|
||||
naming_strategy: wallabag_core.doctrine.prefixed_naming_strategy
|
||||
auto_mapping: true
|
||||
|
||||
# Swiftmailer Configuration
|
||||
swiftmailer:
|
||||
transport: "%mailer_transport%"
|
||||
host: "%mailer_host%"
|
||||
username: "%mailer_user%"
|
||||
password: "%mailer_password%"
|
||||
spool: { type: memory }
|
||||
|
||||
fos_rest:
|
||||
param_fetcher_listener: true
|
||||
body_listener: true
|
||||
format_listener: true
|
||||
view:
|
||||
view_response_listener: 'force'
|
||||
formats:
|
||||
xml: true
|
||||
json : true
|
||||
templating_formats:
|
||||
html: true
|
||||
force_redirects:
|
||||
html: true
|
||||
failed_validation: HTTP_BAD_REQUEST
|
||||
default_engine: twig
|
||||
routing_loader:
|
||||
default_format: json
|
||||
|
||||
nelmio_api_doc: ~
|
||||
|
||||
nelmio_cors:
|
||||
defaults:
|
||||
allow_credentials: false
|
||||
allow_origin: []
|
||||
allow_headers: []
|
||||
allow_methods: []
|
||||
expose_headers: []
|
||||
max_age: 0
|
||||
hosts: []
|
||||
#origin_regex: false
|
||||
paths:
|
||||
'^/api/':
|
||||
allow_origin: ['*']
|
||||
allow_headers: ['X-Custom-Auth']
|
||||
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
|
||||
max_age: 3600
|
||||
'^/':
|
||||
#origin_regex: true
|
||||
allow_origin: ['^http://localhost:[0-9]+']
|
||||
allow_headers: ['X-Custom-Auth']
|
||||
allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
|
||||
max_age: 3600
|
||||
hosts: ['^api\.']
|
||||
|
||||
liip_theme:
|
||||
load_controllers: false
|
||||
themes:
|
||||
- baggy
|
||||
- material
|
||||
autodetect_theme: wallabag_core.helper.detect_active_theme
|
||||
|
||||
path_patterns:
|
||||
# app_resource:
|
||||
# - %%app_path%%/views/themes/%%current_theme%%/%%template%%
|
||||
# - %%app_path%%/views/%%template%%
|
||||
bundle_resource:
|
||||
- %%bundle_path%%/Resources/views/themes/%%current_theme%%/%%template%%
|
||||
# bundle_resource_dir:
|
||||
# - %%dir%%/views/themes/%%current_theme%%/%%bundle_name%%/%%template%%
|
||||
# - %%dir%%/views/%%bundle_name%%/%%override_path%%
|
||||
|
||||
fos_user:
|
||||
db_driver: orm
|
||||
firewall_name: main
|
||||
user_class: Wallabag\CoreBundle\Entity\User
|
||||
54
app/config/config_dev.yml
Normal file
54
app/config/config_dev.yml
Normal file
@ -0,0 +1,54 @@
|
||||
imports:
|
||||
- { resource: config.yml }
|
||||
|
||||
framework:
|
||||
router:
|
||||
resource: "%kernel.root_dir%/config/routing_dev.yml"
|
||||
strict_requirements: true
|
||||
profiler: { only_exceptions: false }
|
||||
|
||||
web_profiler:
|
||||
toolbar: true
|
||||
intercept_redirects: false
|
||||
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
console:
|
||||
type: console
|
||||
bubble: false
|
||||
verbosity_levels:
|
||||
VERBOSITY_VERBOSE: INFO
|
||||
VERBOSITY_VERY_VERBOSE: DEBUG
|
||||
channels: ["!doctrine"]
|
||||
console_very_verbose:
|
||||
type: console
|
||||
bubble: false
|
||||
verbosity_levels:
|
||||
VERBOSITY_VERBOSE: NOTICE
|
||||
VERBOSITY_VERY_VERBOSE: NOTICE
|
||||
VERBOSITY_DEBUG: DEBUG
|
||||
channels: ["doctrine"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
|
||||
assetic:
|
||||
use_controller: true
|
||||
|
||||
swiftmailer:
|
||||
# see http://mailcatcher.me/
|
||||
transport: smtp
|
||||
host: 'localhost'
|
||||
port: 1025
|
||||
username: null
|
||||
password: null
|
||||
|
||||
30
app/config/config_prod.yml
Normal file
30
app/config/config_prod.yml
Normal file
@ -0,0 +1,30 @@
|
||||
imports:
|
||||
- { resource: config.yml }
|
||||
|
||||
#framework:
|
||||
# validation:
|
||||
# cache: apc
|
||||
|
||||
#doctrine:
|
||||
# orm:
|
||||
# metadata_cache_driver: apc
|
||||
# result_cache_driver: apc
|
||||
# query_cache_driver: apc
|
||||
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
wsse:
|
||||
type: stream
|
||||
path: %kernel.logs_dir%/%kernel.environment%.wsse.log
|
||||
level: error
|
||||
channels: [wsse]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
console:
|
||||
type: console
|
||||
31
app/config/config_test.yml
Normal file
31
app/config/config_test.yml
Normal file
@ -0,0 +1,31 @@
|
||||
imports:
|
||||
- { resource: config_dev.yml }
|
||||
|
||||
framework:
|
||||
test: ~
|
||||
session:
|
||||
storage_id: session.storage.mock_file
|
||||
profiler:
|
||||
collect: false
|
||||
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
swiftmailer:
|
||||
# to be able to read emails sent
|
||||
spool:
|
||||
type: file
|
||||
|
||||
doctrine:
|
||||
dbal:
|
||||
driver: pdo_sqlite
|
||||
path: %kernel.root_dir%/../data/db/wallabag_test.sqlite
|
||||
host: localhost
|
||||
orm:
|
||||
metadata_cache_driver:
|
||||
type: service
|
||||
id: filesystem_cache
|
||||
query_cache_driver:
|
||||
type: service
|
||||
id: filesystem_cache
|
||||
50
app/config/parameters.yml.dist
Normal file
50
app/config/parameters.yml.dist
Normal file
@ -0,0 +1,50 @@
|
||||
# This file is a "template" of what your parameters.yml file should look like
|
||||
parameters:
|
||||
database_driver: pdo_sqlite
|
||||
database_host: 127.0.0.1
|
||||
database_port: ~
|
||||
database_name: symfony
|
||||
database_user: root
|
||||
database_password: ~
|
||||
database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite"
|
||||
database_table_prefix: wallabag_
|
||||
|
||||
mailer_transport: smtp
|
||||
mailer_host: 127.0.0.1
|
||||
mailer_user: ~
|
||||
mailer_password: ~
|
||||
|
||||
locale: en
|
||||
|
||||
# A secret key that's used to generate certain security-related tokens
|
||||
secret: ThisTokenIsNotSoSecretChangeIt
|
||||
|
||||
# wallabag misc
|
||||
app.version: 2.0.0-alpha
|
||||
|
||||
# message to display at the bottom of the page
|
||||
warning_message: >
|
||||
You're trying wallabag v2, which is in alpha version. If you find a bug, please have a look to <a href="https://github.com/wallabag/wallabag/issues">our issues list</a> and <a href="https://github.com/wallabag/wallabag/issues/new">open a new if necessary</a>
|
||||
|
||||
download_pictures: false # if true, pictures will be stored into data/assets for each article
|
||||
|
||||
# Entry view
|
||||
share_twitter: true
|
||||
share_mail: true
|
||||
share_shaarli: true
|
||||
shaarli_url: http://myshaarli.com
|
||||
share_diaspora: true
|
||||
diaspora_url: http://diasporapod.com
|
||||
flattr: true
|
||||
carrot: true
|
||||
show_printlink: true
|
||||
export_epub: true
|
||||
export_mobi: true
|
||||
export_pdf: true
|
||||
|
||||
# default user config
|
||||
items_on_page: 12
|
||||
theme: material
|
||||
language: en_US
|
||||
from_email: no-reply@wallabag.org
|
||||
rss_limit: 50
|
||||
32
app/config/routing.yml
Normal file
32
app/config/routing.yml
Normal file
@ -0,0 +1,32 @@
|
||||
wallabag_api:
|
||||
resource: "@WallabagApiBundle/Resources/config/routing.yml"
|
||||
prefix: /
|
||||
|
||||
app:
|
||||
resource: @WallabagCoreBundle/Controller/
|
||||
type: annotation
|
||||
|
||||
doc-api:
|
||||
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
|
||||
prefix: /api/doc
|
||||
|
||||
login:
|
||||
pattern: /login
|
||||
defaults: { _controller: WallabagCoreBundle:Security:login }
|
||||
|
||||
login_check:
|
||||
pattern: /login_check
|
||||
|
||||
logout:
|
||||
path: /logout
|
||||
|
||||
rest :
|
||||
type : rest
|
||||
resource : "routing_rest.yml"
|
||||
prefix : /api
|
||||
|
||||
homepage:
|
||||
pattern: "/{page}"
|
||||
defaults: { _controller: WallabagCoreBundle:Entry:showUnread, page : 1 }
|
||||
requirements:
|
||||
page: \d+
|
||||
18
app/config/routing_dev.yml
Normal file
18
app/config/routing_dev.yml
Normal file
@ -0,0 +1,18 @@
|
||||
_wdt:
|
||||
resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
|
||||
prefix: /_wdt
|
||||
|
||||
_profiler:
|
||||
resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
|
||||
prefix: /_profiler
|
||||
|
||||
_configurator:
|
||||
resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml"
|
||||
prefix: /_configurator
|
||||
|
||||
_errors:
|
||||
resource: "@TwigBundle/Resources/config/routing/errors.xml"
|
||||
prefix: /_error
|
||||
|
||||
_main:
|
||||
resource: routing.yml
|
||||
3
app/config/routing_rest.yml
Normal file
3
app/config/routing_rest.yml
Normal file
@ -0,0 +1,3 @@
|
||||
Rest_Wallabag:
|
||||
type : rest
|
||||
resource: "@WallabagApiBundle/Resources/config/routing_rest.yml"
|
||||
53
app/config/security.yml
Normal file
53
app/config/security.yml
Normal file
@ -0,0 +1,53 @@
|
||||
security:
|
||||
encoders:
|
||||
Wallabag\CoreBundle\Entity\User:
|
||||
algorithm: sha1
|
||||
encode_as_base64: false
|
||||
iterations: 1
|
||||
|
||||
role_hierarchy:
|
||||
ROLE_ADMIN: ROLE_USER
|
||||
ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
|
||||
|
||||
providers:
|
||||
administrators:
|
||||
entity: { class: WallabagCoreBundle:User, property: username }
|
||||
fos_userbundle:
|
||||
id: fos_user.user_provider.username
|
||||
|
||||
# the main part of the security, where you can set up firewalls
|
||||
# for specific sections of your app
|
||||
firewalls:
|
||||
wsse_secured:
|
||||
pattern: /api/.*
|
||||
wsse: true
|
||||
stateless: true
|
||||
anonymous: true
|
||||
login_firewall:
|
||||
pattern: ^/login$
|
||||
anonymous: ~
|
||||
|
||||
secured_area:
|
||||
pattern: ^/
|
||||
form_login:
|
||||
provider: fos_userbundle
|
||||
csrf_provider: security.csrf.token_manager
|
||||
|
||||
anonymous: true
|
||||
remember_me:
|
||||
key: "%secret%"
|
||||
lifetime: 31536000
|
||||
path: /
|
||||
domain: ~
|
||||
|
||||
logout:
|
||||
path: /logout
|
||||
target: /
|
||||
|
||||
access_control:
|
||||
- { path: ^/api/salt, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/, roles: ROLE_USER }
|
||||
19
app/config/services.yml
Normal file
19
app/config/services.yml
Normal file
@ -0,0 +1,19 @@
|
||||
# Learn more about services, parameters and containers at
|
||||
# http://symfony.com/doc/current/book/service_container.html
|
||||
parameters:
|
||||
security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider
|
||||
security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder
|
||||
security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator
|
||||
lexik_form_filter.get_filter.doctrine_orm.class: Wallabag\CoreBundle\Event\Subscriber\CustomDoctrineORMSubscriber
|
||||
|
||||
services:
|
||||
# used for tests
|
||||
filesystem_cache:
|
||||
class: Doctrine\Common\Cache\FilesystemCache
|
||||
arguments:
|
||||
- %kernel.cache_dir%/doctrine/metadata
|
||||
|
||||
twig.extension.text:
|
||||
class: Twig_Extensions_Extension_Text
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
27
app/console
Executable file
27
app/console
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
|
||||
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
|
||||
//umask(0000);
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
require_once __DIR__.'/bootstrap.php.cache';
|
||||
require_once __DIR__.'/AppKernel.php';
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Debug\Debug;
|
||||
|
||||
$input = new ArgvInput();
|
||||
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
|
||||
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
|
||||
|
||||
if ($debug) {
|
||||
Debug::enable();
|
||||
}
|
||||
|
||||
$kernel = new AppKernel($env, $debug);
|
||||
$application = new Application($kernel);
|
||||
$application->run($input);
|
||||
1
bin/phpunit
Symbolic link
1
bin/phpunit
Symbolic link
@ -0,0 +1 @@
|
||||
../vendor/phpunit/phpunit/phpunit
|
||||
BIN
install/poche.sqlite → bin/poche.sqlite
Executable file → Normal file
BIN
install/poche.sqlite → bin/poche.sqlite
Executable file → Normal file
Binary file not shown.
50
build.xml
Normal file
50
build.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="wallabag" default="build">
|
||||
<target name="build" depends="prepare"/>
|
||||
|
||||
<target name="clean" description="Cleanup build artifacts">
|
||||
<delete dir="${basedir}/app/cache"/>
|
||||
</target>
|
||||
|
||||
<target name="prepare" depends="clean" description="Prepare for build">
|
||||
<exec executable="composer">
|
||||
<arg value="install"/>
|
||||
<arg value="--no-interaction"/>
|
||||
<arg value="--no-progress"/>
|
||||
</exec>
|
||||
<exec executable="php">
|
||||
<arg value="${basedir}/app/console"/>
|
||||
<arg value="doctrine:database:drop"/>
|
||||
<arg value="--force"/>
|
||||
<arg value="--env=test"/>
|
||||
</exec>
|
||||
<exec executable="php">
|
||||
<arg value="${basedir}/app/console"/>
|
||||
<arg value="doctrine:database:create"/>
|
||||
<arg value="--env=test"/>
|
||||
</exec>
|
||||
<exec executable="php">
|
||||
<arg value="${basedir}/app/console"/>
|
||||
<arg value="doctrine:schema:create"/>
|
||||
<arg value="--env=test"/>
|
||||
</exec>
|
||||
<exec executable="php">
|
||||
<arg value="${basedir}/app/console"/>
|
||||
<arg value="cache:clear"/>
|
||||
<arg value="--env=test"/>
|
||||
</exec>
|
||||
<exec executable="php">
|
||||
<arg value="${basedir}/app/console"/>
|
||||
<arg value="doctrine:fixtures:load"/>
|
||||
<arg value="--no-interaction"/>
|
||||
<arg value="--env=test"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpunit" description="Run unit tests with PHPUnit + HTML Coverage">
|
||||
<exec executable="phpunit" failonerror="true">
|
||||
<arg value="--coverage-html"/>
|
||||
<arg value="build/coverage"/>
|
||||
</exec>
|
||||
</target>
|
||||
</project>
|
||||
@ -1,7 +1,95 @@
|
||||
{
|
||||
"name": "wallabag/wallabag",
|
||||
"type": "project",
|
||||
"description": "open source self hostable read-it-later web application",
|
||||
"keywords": ["read-it-later","read it later"],
|
||||
"homepage": "https://github.com/wallabag/wallabag",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Lœuillet",
|
||||
"email": "nicolas@loeuillet.org",
|
||||
"homepage": "http://www.cdetc.fr",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Thomas Citharel",
|
||||
"homepage": "http://tcit.fr",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Jérémy Benoist",
|
||||
"homepage": "http://www.j0k3r.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "hello@wallabag.org",
|
||||
"issues": "https://github.com/wallabag/wallabag/issues"
|
||||
},
|
||||
"require": {
|
||||
"twig/twig": "1.*",
|
||||
"twig/extensions": "1.0.*",
|
||||
"umpirsky/twig-gettext-extractor": "1.1.*"
|
||||
}
|
||||
}
|
||||
"php": ">=5.3.3",
|
||||
"symfony/symfony": "~2.7.0",
|
||||
"doctrine/orm": "~2.3",
|
||||
"doctrine/doctrine-bundle": "~1.2",
|
||||
"twig/extensions": "~1.0",
|
||||
"symfony/assetic-bundle": "~2.3",
|
||||
"symfony/swiftmailer-bundle": "~2.3",
|
||||
"symfony/monolog-bundle": "~2.4",
|
||||
"sensio/distribution-bundle": "~3.0.12",
|
||||
"sensio/framework-extra-bundle": "~3.0",
|
||||
"incenteev/composer-parameter-handler": "~2.0",
|
||||
"nelmio/cors-bundle": "~1.4.0",
|
||||
"friendsofsymfony/rest-bundle": "~1.4",
|
||||
"jms/serializer-bundle": "~0.13",
|
||||
"nelmio/api-doc-bundle": "~2.7",
|
||||
"ezyang/htmlpurifier": "~4.6",
|
||||
"mgargano/simplehtmldom": "~1.5",
|
||||
"tecnick.com/tcpdf": "~6.2",
|
||||
"simplepie/simplepie": "~1.3.1",
|
||||
"willdurand/hateoas-bundle": "~0.5.0",
|
||||
"htmlawed/htmlawed": "~1.1.19",
|
||||
"liip/theme-bundle": "~1.1.3",
|
||||
"pagerfanta/pagerfanta": "~1.0.3",
|
||||
"lexik/form-filter-bundle": "~4.0",
|
||||
"j0k3r/graby": "~1.0",
|
||||
"friendsofsymfony/user-bundle": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-fixtures-bundle": "~2.2.0",
|
||||
"sensio/generator-bundle": "~2.5",
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
|
||||
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"symfony-app-dir": "app",
|
||||
"symfony-web-dir": "web",
|
||||
"symfony-assets-install": "relative",
|
||||
"incenteev-parameters": {
|
||||
"file": "app/config/parameters.yml"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "": "src/" }
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "bin"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
||||
4643
composer.lock
generated
4643
composer.lock
generated
File diff suppressed because it is too large
Load Diff
66
config/deploy.rb
Normal file
66
config/deploy.rb
Normal file
@ -0,0 +1,66 @@
|
||||
# config valid only for current version of Capistrano
|
||||
lock '3.4.0'
|
||||
|
||||
set :application, 'wallabag'
|
||||
set :repo_url, 'git@github.com:wallabag/wallabag.git'
|
||||
|
||||
set :ssh_user, 'ssh_user'
|
||||
server 'server_ip', user: fetch(:ssh_user), roles: %w{web app db}
|
||||
|
||||
set :scm, :git
|
||||
|
||||
set :format, :pretty
|
||||
set :log_level, :info
|
||||
# set :log_level, :debug
|
||||
|
||||
set :composer_install_flags, '--no-dev --prefer-dist --no-interaction --optimize-autoloader'
|
||||
|
||||
set :linked_files, %w{app/config/parameters.yml}
|
||||
set :linked_dirs, %w{app/logs web/uploads}
|
||||
|
||||
set :keep_releases, 3
|
||||
|
||||
after 'deploy:finishing', 'deploy:cleanup'
|
||||
|
||||
# Default branch is :master
|
||||
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
|
||||
|
||||
# Default deploy_to directory is /var/www/my_app_name
|
||||
# set :deploy_to, '/var/www/my_app_name'
|
||||
|
||||
# Default value for :scm is :git
|
||||
# set :scm, :git
|
||||
|
||||
# Default value for :format is :pretty
|
||||
# set :format, :pretty
|
||||
|
||||
# Default value for :log_level is :debug
|
||||
# set :log_level, :debug
|
||||
|
||||
# Default value for :pty is false
|
||||
# set :pty, true
|
||||
|
||||
# Default value for :linked_files is []
|
||||
# set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
|
||||
|
||||
# Default value for linked_dirs is []
|
||||
# set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system')
|
||||
|
||||
# Default value for default_env is {}
|
||||
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
|
||||
|
||||
# Default value for keep_releases is 5
|
||||
# set :keep_releases, 5
|
||||
|
||||
namespace :deploy do
|
||||
|
||||
after :restart, :clear_cache do
|
||||
on roles(:web), in: :groups, limit: 3, wait: 10 do
|
||||
# Here we can do anything such as:
|
||||
# within release_path do
|
||||
# execute :rake, 'cache:clear'
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
61
config/deploy/production.rb
Normal file
61
config/deploy/production.rb
Normal file
@ -0,0 +1,61 @@
|
||||
# server-based syntax
|
||||
# ======================
|
||||
# Defines a single server with a list of roles and multiple properties.
|
||||
# You can define all roles on a single server, or split them:
|
||||
|
||||
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
|
||||
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
||||
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
||||
|
||||
|
||||
|
||||
# role-based syntax
|
||||
# ==================
|
||||
|
||||
# Defines a role with one or multiple servers. The primary server in each
|
||||
# group is considered to be the first unless any hosts have the primary
|
||||
# property set. Specify the username and a domain or IP for the server.
|
||||
# Don't use `:all`, it's a meta role.
|
||||
|
||||
# role :app, %w{deploy@example.com}, my_property: :my_value
|
||||
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
||||
# role :db, %w{deploy@example.com}
|
||||
|
||||
|
||||
|
||||
# Configuration
|
||||
# =============
|
||||
# You can set any configuration variable like in config/deploy.rb
|
||||
# These variables are then only loaded and set in this stage.
|
||||
# For available Capistrano configuration variables see the documentation page.
|
||||
# http://capistranorb.com/documentation/getting-started/configuration/
|
||||
# Feel free to add new variables to customise your setup.
|
||||
|
||||
|
||||
|
||||
# Custom SSH Options
|
||||
# ==================
|
||||
# You may pass any option but keep in mind that net/ssh understands a
|
||||
# limited set of options, consult the Net::SSH documentation.
|
||||
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
|
||||
#
|
||||
# Global options
|
||||
# --------------
|
||||
# set :ssh_options, {
|
||||
# keys: %w(/home/rlisowski/.ssh/id_rsa),
|
||||
# forward_agent: false,
|
||||
# auth_methods: %w(password)
|
||||
# }
|
||||
#
|
||||
# The server-based syntax can be used to override options:
|
||||
# ------------------------------------
|
||||
# server 'example.com',
|
||||
# user: 'user_name',
|
||||
# roles: %w{web app},
|
||||
# ssh_options: {
|
||||
# user: 'user_name', # overrides user setting above
|
||||
# keys: %w(/home/user_name/.ssh/id_rsa),
|
||||
# forward_agent: false,
|
||||
# auth_methods: %w(publickey password)
|
||||
# # password: 'please use keys'
|
||||
# }
|
||||
64
config/deploy/staging.rb
Normal file
64
config/deploy/staging.rb
Normal file
@ -0,0 +1,64 @@
|
||||
# server-based syntax
|
||||
# ======================
|
||||
# Defines a single server with a list of roles and multiple properties.
|
||||
# You can define all roles on a single server, or split them:
|
||||
|
||||
set :branch, 'v2'
|
||||
set :deploy_to, '/var/www/'
|
||||
|
||||
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
|
||||
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
|
||||
# server 'db.example.com', user: 'deploy', roles: %w{db}
|
||||
|
||||
|
||||
|
||||
# role-based syntax
|
||||
# ==================
|
||||
|
||||
# Defines a role with one or multiple servers. The primary server in each
|
||||
# group is considered to be the first unless any hosts have the primary
|
||||
# property set. Specify the username and a domain or IP for the server.
|
||||
# Don't use `:all`, it's a meta role.
|
||||
|
||||
# role :app, %w{deploy@example.com}, my_property: :my_value
|
||||
# role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value
|
||||
# role :db, %w{deploy@example.com}
|
||||
|
||||
|
||||
|
||||
# Configuration
|
||||
# =============
|
||||
# You can set any configuration variable like in config/deploy.rb
|
||||
# These variables are then only loaded and set in this stage.
|
||||
# For available Capistrano configuration variables see the documentation page.
|
||||
# http://capistranorb.com/documentation/getting-started/configuration/
|
||||
# Feel free to add new variables to customise your setup.
|
||||
|
||||
|
||||
|
||||
# Custom SSH Options
|
||||
# ==================
|
||||
# You may pass any option but keep in mind that net/ssh understands a
|
||||
# limited set of options, consult the Net::SSH documentation.
|
||||
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
|
||||
#
|
||||
# Global options
|
||||
# --------------
|
||||
# set :ssh_options, {
|
||||
# keys: %w(/home/rlisowski/.ssh/id_rsa),
|
||||
# forward_agent: false,
|
||||
# auth_methods: %w(password)
|
||||
# }
|
||||
#
|
||||
# The server-based syntax can be used to override options:
|
||||
# ------------------------------------
|
||||
# server 'example.com',
|
||||
# user: 'user_name',
|
||||
# roles: %w{web app},
|
||||
# ssh_options: {
|
||||
# user: 'user_name', # overrides user setting above
|
||||
# keys: %w(/home/user_name/.ssh/id_rsa),
|
||||
# forward_agent: false,
|
||||
# auth_methods: %w(publickey password)
|
||||
# # password: 'please use keys'
|
||||
# }
|
||||
0
db/.gitignore → data/assets/.gitignore
vendored
0
db/.gitignore → data/assets/.gitignore
vendored
0
data/db/.gitignore
vendored
Normal file
0
data/db/.gitignore
vendored
Normal file
262
inc/3rdparty/Encoding.php
vendored
262
inc/3rdparty/Encoding.php
vendored
@ -1,262 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @author "Sebastián Grignoli" <grignoli@framework2.com.ar>
|
||||
* @package Encoding
|
||||
* @version 1.1
|
||||
* @link http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
* @example http://www.framework2.com.ar/dzone/forceUTF8-es/
|
||||
*/
|
||||
|
||||
class Encoding {
|
||||
|
||||
protected static $win1252ToUtf8 = array(
|
||||
128 => "\xe2\x82\xac",
|
||||
|
||||
130 => "\xe2\x80\x9a",
|
||||
131 => "\xc6\x92",
|
||||
132 => "\xe2\x80\x9e",
|
||||
133 => "\xe2\x80\xa6",
|
||||
134 => "\xe2\x80\xa0",
|
||||
135 => "\xe2\x80\xa1",
|
||||
136 => "\xcb\x86",
|
||||
137 => "\xe2\x80\xb0",
|
||||
138 => "\xc5\xa0",
|
||||
139 => "\xe2\x80\xb9",
|
||||
140 => "\xc5\x92",
|
||||
|
||||
142 => "\xc5\xbd",
|
||||
|
||||
|
||||
145 => "\xe2\x80\x98",
|
||||
146 => "\xe2\x80\x99",
|
||||
147 => "\xe2\x80\x9c",
|
||||
148 => "\xe2\x80\x9d",
|
||||
149 => "\xe2\x80\xa2",
|
||||
150 => "\xe2\x80\x93",
|
||||
151 => "\xe2\x80\x94",
|
||||
152 => "\xcb\x9c",
|
||||
153 => "\xe2\x84\xa2",
|
||||
154 => "\xc5\xa1",
|
||||
155 => "\xe2\x80\xba",
|
||||
156 => "\xc5\x93",
|
||||
|
||||
158 => "\xc5\xbe",
|
||||
159 => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $brokenUtf8ToUtf8 = array(
|
||||
"\xc2\x80" => "\xe2\x82\xac",
|
||||
|
||||
"\xc2\x82" => "\xe2\x80\x9a",
|
||||
"\xc2\x83" => "\xc6\x92",
|
||||
"\xc2\x84" => "\xe2\x80\x9e",
|
||||
"\xc2\x85" => "\xe2\x80\xa6",
|
||||
"\xc2\x86" => "\xe2\x80\xa0",
|
||||
"\xc2\x87" => "\xe2\x80\xa1",
|
||||
"\xc2\x88" => "\xcb\x86",
|
||||
"\xc2\x89" => "\xe2\x80\xb0",
|
||||
"\xc2\x8a" => "\xc5\xa0",
|
||||
"\xc2\x8b" => "\xe2\x80\xb9",
|
||||
"\xc2\x8c" => "\xc5\x92",
|
||||
|
||||
"\xc2\x8e" => "\xc5\xbd",
|
||||
|
||||
|
||||
"\xc2\x91" => "\xe2\x80\x98",
|
||||
"\xc2\x92" => "\xe2\x80\x99",
|
||||
"\xc2\x93" => "\xe2\x80\x9c",
|
||||
"\xc2\x94" => "\xe2\x80\x9d",
|
||||
"\xc2\x95" => "\xe2\x80\xa2",
|
||||
"\xc2\x96" => "\xe2\x80\x93",
|
||||
"\xc2\x97" => "\xe2\x80\x94",
|
||||
"\xc2\x98" => "\xcb\x9c",
|
||||
"\xc2\x99" => "\xe2\x84\xa2",
|
||||
"\xc2\x9a" => "\xc5\xa1",
|
||||
"\xc2\x9b" => "\xe2\x80\xba",
|
||||
"\xc2\x9c" => "\xc5\x93",
|
||||
|
||||
"\xc2\x9e" => "\xc5\xbe",
|
||||
"\xc2\x9f" => "\xc5\xb8"
|
||||
);
|
||||
|
||||
protected static $utf8ToWin1252 = array(
|
||||
"\xe2\x82\xac" => "\x80",
|
||||
|
||||
"\xe2\x80\x9a" => "\x82",
|
||||
"\xc6\x92" => "\x83",
|
||||
"\xe2\x80\x9e" => "\x84",
|
||||
"\xe2\x80\xa6" => "\x85",
|
||||
"\xe2\x80\xa0" => "\x86",
|
||||
"\xe2\x80\xa1" => "\x87",
|
||||
"\xcb\x86" => "\x88",
|
||||
"\xe2\x80\xb0" => "\x89",
|
||||
"\xc5\xa0" => "\x8a",
|
||||
"\xe2\x80\xb9" => "\x8b",
|
||||
"\xc5\x92" => "\x8c",
|
||||
|
||||
"\xc5\xbd" => "\x8e",
|
||||
|
||||
|
||||
"\xe2\x80\x98" => "\x91",
|
||||
"\xe2\x80\x99" => "\x92",
|
||||
"\xe2\x80\x9c" => "\x93",
|
||||
"\xe2\x80\x9d" => "\x94",
|
||||
"\xe2\x80\xa2" => "\x95",
|
||||
"\xe2\x80\x93" => "\x96",
|
||||
"\xe2\x80\x94" => "\x97",
|
||||
"\xcb\x9c" => "\x98",
|
||||
"\xe2\x84\xa2" => "\x99",
|
||||
"\xc5\xa1" => "\x9a",
|
||||
"\xe2\x80\xba" => "\x9b",
|
||||
"\xc5\x93" => "\x9c",
|
||||
|
||||
"\xc5\xbe" => "\x9e",
|
||||
"\xc5\xb8" => "\x9f"
|
||||
);
|
||||
|
||||
static function toUTF8($text){
|
||||
/**
|
||||
* Function Encoding::toUTF8
|
||||
*
|
||||
* This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
|
||||
*
|
||||
* It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
|
||||
*
|
||||
* It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
|
||||
*
|
||||
* 1) when any of these characters: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß
|
||||
* are followed by any of these: ("group B")
|
||||
* ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶•¸¹º»¼½¾¿
|
||||
* For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
|
||||
* The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
|
||||
* is also a valid unicode character, and will be left unchanged.
|
||||
*
|
||||
* 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
|
||||
* 3) when any of these: ðñòó are followed by THREE chars from group B.
|
||||
*
|
||||
* @name toUTF8
|
||||
* @param string $text Any string.
|
||||
* @return string The same string, UTF8 encoded
|
||||
*
|
||||
*/
|
||||
|
||||
if(is_array($text))
|
||||
{
|
||||
foreach($text as $k => $v)
|
||||
{
|
||||
$text[$k] = self::toUTF8($v);
|
||||
}
|
||||
return $text;
|
||||
} elseif(is_string($text)) {
|
||||
|
||||
$max = strlen($text);
|
||||
$buf = "";
|
||||
for($i = 0; $i < $max; $i++){
|
||||
$c1 = $text{$i};
|
||||
if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
|
||||
$c2 = $i+1 >= $max? "\x00" : $text{$i+1};
|
||||
$c3 = $i+2 >= $max? "\x00" : $text{$i+2};
|
||||
$c4 = $i+3 >= $max? "\x00" : $text{$i+3};
|
||||
if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2;
|
||||
$i++;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xe0" & $c1 <= "\xef"){ //looks like 3 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3;
|
||||
$i = $i + 2;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif($c1 >= "\xf0" & $c1 <= "\xf7"){ //looks like 4 bytes UTF8
|
||||
if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf"){ //yeah, almost sure it's UTF8 already
|
||||
$buf .= $c1 . $c2 . $c3;
|
||||
$i = $i + 2;
|
||||
} else { //not valid UTF8. Convert it.
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = ($c1 & "\x3f") | "\x80";
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { //doesn't look like UTF8, but should be converted
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} elseif(($c1 & "\xc0") == "\x80"){ // needs conversion
|
||||
if(isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
|
||||
$buf .= self::$win1252ToUtf8[ord($c1)];
|
||||
} else {
|
||||
$cc1 = (chr(ord($c1) / 64) | "\xc0");
|
||||
$cc2 = (($c1 & "\x3f") | "\x80");
|
||||
$buf .= $cc1 . $cc2;
|
||||
}
|
||||
} else { // it doesn't need convesion
|
||||
$buf .= $c1;
|
||||
}
|
||||
}
|
||||
return $buf;
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
static function toWin1252($text) {
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::toWin1252($v);
|
||||
}
|
||||
return $text;
|
||||
} elseif(is_string($text)) {
|
||||
return utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text)));
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
static function toISO8859($text) {
|
||||
return self::toWin1252($text);
|
||||
}
|
||||
|
||||
static function toLatin1($text) {
|
||||
return self::toWin1252($text);
|
||||
}
|
||||
|
||||
static function fixUTF8($text){
|
||||
if(is_array($text)) {
|
||||
foreach($text as $k => $v) {
|
||||
$text[$k] = self::fixUTF8($v);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
$last = "";
|
||||
while($last <> $text){
|
||||
$last = $text;
|
||||
$text = self::toUTF8(utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), $text)));
|
||||
}
|
||||
$text = self::toUTF8(utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), $text)));
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function UTF8FixWin1252Chars($text){
|
||||
// If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
|
||||
// (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
|
||||
// See: http://en.wikipedia.org/wiki/Windows-1252
|
||||
|
||||
return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
|
||||
}
|
||||
|
||||
static function removeBOM($str=""){
|
||||
if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
|
||||
$str=substr($str, 3);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
49
inc/3rdparty/FlattrItem.class.php
vendored
49
inc/3rdparty/FlattrItem.class.php
vendored
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* Class for Flattr querying
|
||||
*/
|
||||
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 ($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
109
inc/3rdparty/JSLikeHTMLElement.php
vendored
109
inc/3rdparty/JSLikeHTMLElement.php
vendored
@ -1,109 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* JavaScript-like HTML DOM Element
|
||||
*
|
||||
* This class extends PHP's DOMElement to allow
|
||||
* users to get and set the innerHTML property of
|
||||
* HTML elements in the same way it's done in
|
||||
* JavaScript.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* require_once 'JSLikeHTMLElement.php';
|
||||
* header('Content-Type: text/plain');
|
||||
* $doc = new DOMDocument();
|
||||
* $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
|
||||
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
|
||||
* $elem = $doc->getElementsByTagName('div')->item(0);
|
||||
*
|
||||
* // print innerHTML
|
||||
* echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'
|
||||
* echo "\n\n";
|
||||
*
|
||||
* // set innerHTML
|
||||
* $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';
|
||||
* echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'
|
||||
* echo "\n\n";
|
||||
*
|
||||
* // print document (with our changes)
|
||||
* echo $doc->saveXML();
|
||||
* @endcode
|
||||
*
|
||||
* @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net
|
||||
* @see http://fivefilters.org (the project this was written for)
|
||||
*/
|
||||
class JSLikeHTMLElement extends DOMElement
|
||||
{
|
||||
/**
|
||||
* Used for setting innerHTML like it's done in JavaScript:
|
||||
* @code
|
||||
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
|
||||
* @endcode
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
if ($name == 'innerHTML') {
|
||||
// first, empty the element
|
||||
for ($x=$this->childNodes->length-1; $x>=0; $x--) {
|
||||
$this->removeChild($this->childNodes->item($x));
|
||||
}
|
||||
// $value holds our new inner HTML
|
||||
if ($value != '') {
|
||||
$f = $this->ownerDocument->createDocumentFragment();
|
||||
// appendXML() expects well-formed markup (XHTML)
|
||||
$result = @$f->appendXML($value); // @ to suppress PHP warnings
|
||||
if ($result) {
|
||||
if ($f->hasChildNodes()) $this->appendChild($f);
|
||||
} else {
|
||||
// $value is probably ill-formed
|
||||
$f = new DOMDocument();
|
||||
$value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');
|
||||
// Using <htmlfragment> will generate a warning, but so will bad HTML
|
||||
// (and by this point, bad HTML is what we've got).
|
||||
// We use it (and suppress the warning) because an HTML fragment will
|
||||
// be wrapped around <html><body> tags which we don't really want to keep.
|
||||
// Note: despite the warning, if loadHTML succeeds it will return true.
|
||||
$result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>');
|
||||
if ($result) {
|
||||
$import = $f->getElementsByTagName('htmlfragment')->item(0);
|
||||
foreach ($import->childNodes as $child) {
|
||||
$importedNode = $this->ownerDocument->importNode($child, true);
|
||||
$this->appendChild($importedNode);
|
||||
}
|
||||
} else {
|
||||
// oh well, we tried, we really did. :(
|
||||
// this element is now empty
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$trace = debug_backtrace();
|
||||
trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for getting innerHTML like it's done in JavaScript:
|
||||
* @code
|
||||
* $string = $div->innerHTML;
|
||||
* @endcode
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if ($name == 'innerHTML') {
|
||||
$inner = '';
|
||||
foreach ($this->childNodes as $child) {
|
||||
$inner .= $this->ownerDocument->saveXML($child);
|
||||
}
|
||||
return $inner;
|
||||
}
|
||||
|
||||
$trace = debug_backtrace();
|
||||
trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '['.$this->tagName.']';
|
||||
}
|
||||
}
|
||||
1138
inc/3rdparty/Readability.php
vendored
1138
inc/3rdparty/Readability.php
vendored
File diff suppressed because it is too large
Load Diff
279
inc/3rdparty/Session.class.php
vendored
279
inc/3rdparty/Session.class.php
vendored
@ -1,279 +0,0 @@
|
||||
<?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;
|
||||
// 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()
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['HTTP_HOST'], $ssl);
|
||||
// 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,
|
||||
$pValues = array())
|
||||
{
|
||||
self::banInit();
|
||||
if (self::banCanLogin()) {
|
||||
if ($login === $loginTest && $password === $passwordTest) {
|
||||
self::banLoginOk();
|
||||
// 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;
|
||||
|
||||
foreach ($pValues as $key => $value) {
|
||||
$_SESSION[$key] = $value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
self::banLoginFailed();
|
||||
}
|
||||
|
||||
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['poche_user']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
}
|
||||
}
|
||||
231
inc/3rdparty/class.messages.php
vendored
231
inc/3rdparty/class.messages.php
vendored
@ -1,231 +0,0 @@
|
||||
<?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'>X</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
|
||||
?>
|
||||
612
inc/3rdparty/content-extractor/ContentExtractor.php
vendored
612
inc/3rdparty/content-extractor/ContentExtractor.php
vendored
@ -1,612 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Content Extractor
|
||||
*
|
||||
* Uses patterns specified in site config files and auto detection (hNews/PHP Readability)
|
||||
* to extract content from HTML files.
|
||||
*
|
||||
* @version 0.8
|
||||
* @date 2012-02-21
|
||||
* @author Keyvan Minoukadeh
|
||||
* @copyright 2011 Keyvan Minoukadeh
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3
|
||||
*/
|
||||
|
||||
class ContentExtractor
|
||||
{
|
||||
protected static $tidy_config = array(
|
||||
'clean' => true,
|
||||
'output-xhtml' => true,
|
||||
'logical-emphasis' => true,
|
||||
'show-body-only' => false,
|
||||
'new-blocklevel-tags' => 'article, aside, footer, header, hgroup, menu, nav, section, details, datagrid',
|
||||
'new-inline-tags' => 'mark, time, meter, progress, data',
|
||||
'wrap' => 0,
|
||||
'drop-empty-paras' => true,
|
||||
'drop-proprietary-attributes' => false,
|
||||
'enclose-text' => true,
|
||||
'enclose-block-text' => true,
|
||||
'merge-divs' => true,
|
||||
'merge-spans' => true,
|
||||
'char-encoding' => 'utf8',
|
||||
'hide-comments' => true
|
||||
);
|
||||
protected $html;
|
||||
protected $config;
|
||||
protected $title;
|
||||
protected $author = array();
|
||||
protected $language;
|
||||
protected $date;
|
||||
protected $body;
|
||||
protected $success = false;
|
||||
public $fingerprints = array();
|
||||
public $readability;
|
||||
public $debug = false;
|
||||
|
||||
function __construct($path, $fallback=null) {
|
||||
SiteConfig::set_config_path($path, $fallback);
|
||||
}
|
||||
|
||||
protected function debug($msg) {
|
||||
if ($this->debug) {
|
||||
$mem = round(memory_get_usage()/1024, 2);
|
||||
$memPeak = round(memory_get_peak_usage()/1024, 2);
|
||||
echo '* ',$msg;
|
||||
echo ' - mem used: ',$mem," (peak: $memPeak)\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function reset() {
|
||||
$this->html = null;
|
||||
$this->readability = null;
|
||||
$this->config = null;
|
||||
$this->title = null;
|
||||
$this->body = null;
|
||||
$this->author = array();
|
||||
$this->language = null;
|
||||
$this->date = null;
|
||||
$this->success = false;
|
||||
}
|
||||
|
||||
public function findHostUsingFingerprints($html) {
|
||||
$this->debug('Checking fingerprints...');
|
||||
$head = substr($html, 0, 8000);
|
||||
foreach ($this->fingerprints as $_fp => $_fphost) {
|
||||
$lookin = 'html';
|
||||
if (is_array($_fphost)) {
|
||||
if (isset($_fphost['head']) && $_fphost['head']) {
|
||||
$lookin = 'head';
|
||||
}
|
||||
$_fphost = $_fphost['hostname'];
|
||||
}
|
||||
if (strpos($$lookin, $_fp) !== false) {
|
||||
$this->debug("Found match: $_fphost");
|
||||
return $_fphost;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true on success, false on failure
|
||||
// $smart_tidy indicates that if tidy is used and no results are produced, we will
|
||||
// try again without it. Tidy helps us deal with PHP's patchy HTML parsing most of the time
|
||||
// but it has problems of its own which we try to avoid with this option.
|
||||
public function process($html, $url, $smart_tidy=true) {
|
||||
$this->reset();
|
||||
// extract host name
|
||||
$host = @parse_url($url, PHP_URL_HOST);
|
||||
if (!($this->config = SiteConfig::build($host))) {
|
||||
// no match, check HTML for fingerprints
|
||||
if (!empty($this->fingerprints) && ($_fphost = $this->findHostUsingFingerprints($html))) {
|
||||
$this->config = SiteConfig::build($_fphost);
|
||||
}
|
||||
unset($_fphost);
|
||||
if (!$this->config) {
|
||||
// no match, so use defaults
|
||||
$this->config = new SiteConfig();
|
||||
}
|
||||
}
|
||||
// store copy of config in our static cache array in case we need to process another URL
|
||||
SiteConfig::add_to_cache($host, $this->config);
|
||||
|
||||
// do string replacements
|
||||
foreach ($this->config->replace_string as $_repl) {
|
||||
$html = str_replace($_repl[0], $_repl[1], $html);
|
||||
}
|
||||
unset($_repl);
|
||||
|
||||
// use tidy (if it exists)?
|
||||
// This fixes problems with some sites which would otherwise
|
||||
// trouble DOMDocument's HTML parsing. (Although sometimes it
|
||||
// makes matters worse, which is why you can override it in site config files.)
|
||||
$tidied = false;
|
||||
if ($this->config->tidy && function_exists('tidy_parse_string') && $smart_tidy) {
|
||||
$this->debug('Using Tidy');
|
||||
$tidy = tidy_parse_string($html, self::$tidy_config, 'UTF8');
|
||||
if (tidy_clean_repair($tidy)) {
|
||||
$original_html = $html;
|
||||
$tidied = true;
|
||||
// $html = $tidy->value;
|
||||
}
|
||||
$body = $tidy->body();
|
||||
if (preg_replace('/\s+/', '', $body->value) !== "<body></body>") {
|
||||
$html = $tidy->value;
|
||||
}
|
||||
unset($tidy);
|
||||
}
|
||||
|
||||
// load and parse html
|
||||
$this->readability = new PocheReadability($html, $url);
|
||||
|
||||
// we use xpath to find elements in the given HTML document
|
||||
// see http://en.wikipedia.org/wiki/XPath_1.0
|
||||
$xpath = new DOMXPath($this->readability->dom);
|
||||
|
||||
// try to get title
|
||||
foreach ($this->config->title as $pattern) {
|
||||
$elems = @$xpath->evaluate($pattern, $this->readability->dom);
|
||||
if (is_string($elems)) {
|
||||
$this->debug('Title expression evaluated as string');
|
||||
$this->title = trim($elems);
|
||||
break;
|
||||
} elseif ($elems instanceof DOMNodeList && $elems->length > 0) {
|
||||
$this->debug('Title matched');
|
||||
$this->title = $elems->item(0)->textContent;
|
||||
// remove title from document
|
||||
try {
|
||||
$elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
} catch (DOMException $e) {
|
||||
// do nothing
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// try to get author (if it hasn't already been set)
|
||||
if (empty($this->author)) {
|
||||
foreach ($this->config->author as $pattern) {
|
||||
$elems = @$xpath->evaluate($pattern, $this->readability->dom);
|
||||
if (is_string($elems)) {
|
||||
$this->debug('Author expression evaluated as string');
|
||||
if (trim($elems) != '') {
|
||||
$this->author[] = trim($elems);
|
||||
break;
|
||||
}
|
||||
} elseif ($elems instanceof DOMNodeList && $elems->length > 0) {
|
||||
foreach ($elems as $elem) {
|
||||
if (!isset($elem->parentNode)) continue;
|
||||
$this->author[] = trim($elem->textContent);
|
||||
}
|
||||
if (!empty($this->author)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to get language
|
||||
$_lang_xpath = array('//html[@lang]/@lang', '//meta[@name="DC.language"]/@content');
|
||||
foreach ($_lang_xpath as $pattern) {
|
||||
$elems = @$xpath->evaluate($pattern, $this->readability->dom);
|
||||
if (is_string($elems)) {
|
||||
if (trim($elems) != '') {
|
||||
$this->language = trim($elems);
|
||||
break;
|
||||
}
|
||||
} elseif ($elems instanceof DOMNodeList && $elems->length > 0) {
|
||||
foreach ($elems as $elem) {
|
||||
if (!isset($elem->parentNode)) continue;
|
||||
$this->language = trim($elem->textContent);
|
||||
}
|
||||
if ($this->language) break;
|
||||
}
|
||||
}
|
||||
|
||||
// try to get date
|
||||
foreach ($this->config->date as $pattern) {
|
||||
$elems = @$xpath->evaluate($pattern, $this->readability->dom);
|
||||
if (is_string($elems)) {
|
||||
$this->debug('Date expression evaluated as string');
|
||||
$this->date = strtotime(trim($elems, "; \t\n\r\0\x0B"));
|
||||
} elseif ($elems instanceof DOMNodeList && $elems->length > 0) {
|
||||
$this->debug('Date matched');
|
||||
$this->date = $elems->item(0)->textContent;
|
||||
$this->date = strtotime(trim($this->date, "; \t\n\r\0\x0B"));
|
||||
// remove date from document
|
||||
// $elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
}
|
||||
if (!$this->date) {
|
||||
$this->date = null;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// strip elements (using xpath expressions)
|
||||
foreach ($this->config->strip as $pattern) {
|
||||
$elems = @$xpath->query($pattern, $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Stripping '.$elems->length.' elements (strip)');
|
||||
for ($i=$elems->length-1; $i >= 0; $i--) {
|
||||
$elems->item($i)->parentNode->removeChild($elems->item($i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// strip elements (using id and class attribute values)
|
||||
foreach ($this->config->strip_id_or_class as $string) {
|
||||
$string = strtr($string, array("'"=>'', '"'=>''));
|
||||
$elems = @$xpath->query("//*[contains(@class, '$string') or contains(@id, '$string')]", $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Stripping '.$elems->length.' elements (strip_id_or_class)');
|
||||
for ($i=$elems->length-1; $i >= 0; $i--) {
|
||||
$elems->item($i)->parentNode->removeChild($elems->item($i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// strip images (using src attribute values)
|
||||
foreach ($this->config->strip_image_src as $string) {
|
||||
$string = strtr($string, array("'"=>'', '"'=>''));
|
||||
$elems = @$xpath->query("//img[contains(@src, '$string')]", $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Stripping '.$elems->length.' image elements');
|
||||
for ($i=$elems->length-1; $i >= 0; $i--) {
|
||||
$elems->item($i)->parentNode->removeChild($elems->item($i));
|
||||
}
|
||||
}
|
||||
}
|
||||
// strip elements using Readability.com and Instapaper.com ignore class names
|
||||
// .entry-unrelated and .instapaper_ignore
|
||||
// See https://www.readability.com/publishers/guidelines/#view-plainGuidelines
|
||||
// and http://blog.instapaper.com/post/730281947
|
||||
$elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' entry-unrelated ') or contains(concat(' ',normalize-space(@class),' '),' instapaper_ignore ')]", $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Stripping '.$elems->length.' .entry-unrelated,.instapaper_ignore elements');
|
||||
for ($i=$elems->length-1; $i >= 0; $i--) {
|
||||
$elems->item($i)->parentNode->removeChild($elems->item($i));
|
||||
}
|
||||
}
|
||||
|
||||
// strip elements that contain style="display: none;"
|
||||
$elems = @$xpath->query("//*[contains(@style,'display:none')]", $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Stripping '.$elems->length.' elements with inline display:none style');
|
||||
for ($i=$elems->length-1; $i >= 0; $i--) {
|
||||
$elems->item($i)->parentNode->removeChild($elems->item($i));
|
||||
}
|
||||
}
|
||||
|
||||
// try to get body
|
||||
foreach ($this->config->body as $pattern) {
|
||||
$elems = @$xpath->query($pattern, $this->readability->dom);
|
||||
// check for matches
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('Body matched');
|
||||
if ($elems->length == 1) {
|
||||
$this->body = $elems->item(0);
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($this->body);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
$this->body = $this->readability->dom->createElement('div');
|
||||
$this->debug($elems->length.' body elems found');
|
||||
foreach ($elems as $elem) {
|
||||
if (!isset($elem->parentNode)) continue;
|
||||
$isDescendant = false;
|
||||
foreach ($this->body->childNodes as $parent) {
|
||||
if ($this->isDescendant($parent, $elem)) {
|
||||
$isDescendant = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isDescendant) {
|
||||
$this->debug('Element is child of another body element, skipping.');
|
||||
} else {
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($elem);
|
||||
}
|
||||
$this->debug('Element added to body');
|
||||
$this->body->appendChild($elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// auto detect?
|
||||
$detect_title = $detect_body = $detect_author = $detect_date = false;
|
||||
// detect title?
|
||||
if (!isset($this->title)) {
|
||||
if (empty($this->config->title) || $this->config->autodetect_on_failure) {
|
||||
$detect_title = true;
|
||||
}
|
||||
}
|
||||
// detect body?
|
||||
if (!isset($this->body)) {
|
||||
if (empty($this->config->body) || $this->config->autodetect_on_failure) {
|
||||
$detect_body = true;
|
||||
}
|
||||
}
|
||||
// detect author?
|
||||
if (empty($this->author)) {
|
||||
if (empty($this->config->author) || $this->config->autodetect_on_failure) {
|
||||
$detect_author = true;
|
||||
}
|
||||
}
|
||||
// detect date?
|
||||
if (!isset($this->date)) {
|
||||
if (empty($this->config->date) || $this->config->autodetect_on_failure) {
|
||||
$detect_date = true;
|
||||
}
|
||||
}
|
||||
|
||||
// check for hNews
|
||||
if ($detect_title || $detect_body) {
|
||||
// check for hentry
|
||||
$elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' hentry ')]", $this->readability->dom);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('hNews: found hentry');
|
||||
$hentry = $elems->item(0);
|
||||
|
||||
if ($detect_title) {
|
||||
// check for entry-title
|
||||
$elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' entry-title ')]", $hentry);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('hNews: found entry-title');
|
||||
$this->title = $elems->item(0)->textContent;
|
||||
// remove title from document
|
||||
$elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
$detect_title = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($detect_date) {
|
||||
// check for time element with pubdate attribute
|
||||
$elems = @$xpath->query(".//time[@pubdate] | .//abbr[contains(concat(' ',normalize-space(@class),' '),' published ')]", $hentry);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('hNews: found publication date');
|
||||
$this->date = strtotime(trim($elems->item(0)->textContent));
|
||||
// remove date from document
|
||||
//$elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
if ($this->date) {
|
||||
$detect_date = false;
|
||||
} else {
|
||||
$this->date = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($detect_author) {
|
||||
// check for time element with pubdate attribute
|
||||
$elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' vcard ') and (contains(concat(' ',normalize-space(@class),' '),' author ') or contains(concat(' ',normalize-space(@class),' '),' byline '))]", $hentry);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('hNews: found author');
|
||||
$author = $elems->item(0);
|
||||
$fn = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' fn ')]", $author);
|
||||
if ($fn && $fn->length > 0) {
|
||||
foreach ($fn as $_fn) {
|
||||
if (trim($_fn->textContent) != '') {
|
||||
$this->author[] = trim($_fn->textContent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (trim($author->textContent) != '') {
|
||||
$this->author[] = trim($author->textContent);
|
||||
}
|
||||
}
|
||||
$detect_author = empty($this->author);
|
||||
}
|
||||
}
|
||||
|
||||
// check for entry-content.
|
||||
// according to hAtom spec, if there are multiple elements marked entry-content,
|
||||
// we include all of these in the order they appear - see http://microformats.org/wiki/hatom#Entry_Content
|
||||
if ($detect_body) {
|
||||
$elems = @$xpath->query(".//*[contains(concat(' ',normalize-space(@class),' '),' entry-content ')]", $hentry);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('hNews: found entry-content');
|
||||
if ($elems->length == 1) {
|
||||
// what if it's empty? (some sites misuse hNews - place their content outside an empty entry-content element)
|
||||
$e = $elems->item(0);
|
||||
if (($e->tagName == 'img') || (trim($e->textContent) != '')) {
|
||||
$this->body = $elems->item(0);
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($this->body);
|
||||
}
|
||||
$detect_body = false;
|
||||
} else {
|
||||
$this->debug('hNews: skipping entry-content - appears not to contain content');
|
||||
}
|
||||
unset($e);
|
||||
} else {
|
||||
$this->body = $this->readability->dom->createElement('div');
|
||||
$this->debug($elems->length.' entry-content elems found');
|
||||
foreach ($elems as $elem) {
|
||||
if (!isset($elem->parentNode)) continue;
|
||||
$isDescendant = false;
|
||||
foreach ($this->body->childNodes as $parent) {
|
||||
if ($this->isDescendant($parent, $elem)) {
|
||||
$isDescendant = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($isDescendant) {
|
||||
$this->debug('Element is child of another body element, skipping.');
|
||||
} else {
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($elem);
|
||||
}
|
||||
$this->debug('Element added to body');
|
||||
$this->body->appendChild($elem);
|
||||
}
|
||||
}
|
||||
$detect_body = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for elements marked with instapaper_title
|
||||
if ($detect_title) {
|
||||
// check for instapaper_title
|
||||
$elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' instapaper_title ')]", $this->readability->dom);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('title found (.instapaper_title)');
|
||||
$this->title = $elems->item(0)->textContent;
|
||||
// remove title from document
|
||||
$elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
$detect_title = false;
|
||||
}
|
||||
}
|
||||
// check for elements marked with instapaper_body
|
||||
if ($detect_body) {
|
||||
$elems = @$xpath->query("//*[contains(concat(' ',normalize-space(@class),' '),' instapaper_body ')]", $this->readability->dom);
|
||||
if ($elems && $elems->length > 0) {
|
||||
$this->debug('body found (.instapaper_body)');
|
||||
$this->body = $elems->item(0);
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($this->body);
|
||||
}
|
||||
$detect_body = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Find author in rel="author" marked element
|
||||
// We only use this if there's exactly one.
|
||||
// If there's more than one, it could indicate more than
|
||||
// one author, but it could also indicate that we're processing
|
||||
// a page listing different articles with different authors.
|
||||
if ($detect_author) {
|
||||
$elems = @$xpath->query("//a[contains(concat(' ',normalize-space(@rel),' '),' author ')]", $this->readability->dom);
|
||||
if ($elems && $elems->length == 1) {
|
||||
$this->debug('Author found (rel="author")');
|
||||
$author = trim($elems->item(0)->textContent);
|
||||
if ($author != '') {
|
||||
$this->author[] = $author;
|
||||
$detect_author = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find date in pubdate marked time element
|
||||
// For the same reason given above, we only use this
|
||||
// if there's exactly one element.
|
||||
if ($detect_date) {
|
||||
$elems = @$xpath->query("//time[@pubdate]", $this->readability->dom);
|
||||
if ($elems && $elems->length == 1) {
|
||||
$this->debug('Date found (pubdate marked time element)');
|
||||
$this->date = strtotime(trim($elems->item(0)->textContent));
|
||||
// remove date from document
|
||||
//$elems->item(0)->parentNode->removeChild($elems->item(0));
|
||||
if ($this->date) {
|
||||
$detect_date = false;
|
||||
} else {
|
||||
$this->date = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// still missing title or body, so we detect using Readability
|
||||
if ($detect_title || $detect_body) {
|
||||
$this->debug('Using Readability');
|
||||
// clone body if we're only using Readability for title (otherwise it may interfere with body element)
|
||||
if (isset($this->body)) $this->body = $this->body->cloneNode(true);
|
||||
$success = $this->readability->init();
|
||||
}
|
||||
if ($detect_title) {
|
||||
$this->debug('Detecting title');
|
||||
$this->title = $this->readability->getTitle()->textContent;
|
||||
}
|
||||
if ($detect_body && $success) {
|
||||
$this->debug('Detecting body');
|
||||
$this->body = $this->readability->getContent();
|
||||
if ($this->body->childNodes->length == 1 && $this->body->firstChild->nodeType === XML_ELEMENT_NODE) {
|
||||
$this->body = $this->body->firstChild;
|
||||
}
|
||||
// prune (clean up elements that may not be content)
|
||||
if ($this->config->prune) {
|
||||
$this->debug('Pruning content');
|
||||
$this->readability->prepArticle($this->body);
|
||||
}
|
||||
}
|
||||
if (isset($this->body)) {
|
||||
// remove scripts
|
||||
$this->readability->removeScripts($this->body);
|
||||
// remove any h1-h6 elements that appear as first thing in the body
|
||||
// and which match our title
|
||||
if (isset($this->title) && ($this->title != '')) {
|
||||
$firstChild = $this->body->firstChild;
|
||||
while ($firstChild->nodeType && ($firstChild->nodeType !== XML_ELEMENT_NODE)) {
|
||||
$firstChild = $firstChild->nextSibling;
|
||||
}
|
||||
if (($firstChild->nodeType === XML_ELEMENT_NODE)
|
||||
&& in_array(strtolower($firstChild->tagName), array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))
|
||||
&& (strtolower(trim($firstChild->textContent)) == strtolower(trim($this->title)))) {
|
||||
$this->body->removeChild($firstChild);
|
||||
}
|
||||
}
|
||||
$this->success = true;
|
||||
}
|
||||
|
||||
// if we've had no success and we've used tidy, there's a chance
|
||||
// that tidy has messed up. So let's try again without tidy...
|
||||
if (!$this->success && $tidied && $smart_tidy) {
|
||||
$this->debug('Trying again without tidy');
|
||||
$this->process($original_html, $url, false);
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
private function isDescendant(DOMElement $parent, DOMElement $child) {
|
||||
$node = $child->parentNode;
|
||||
while ($node != null) {
|
||||
if ($node->isSameNode($parent)) return true;
|
||||
$node = $node->parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getContent() {
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getAuthors() {
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function getLanguage() {
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function getDate() {
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function getSiteConfig() {
|
||||
return $this->config;
|
||||
}
|
||||
}
|
||||
?>
|
||||
184
inc/3rdparty/content-extractor/SiteConfig.php
vendored
184
inc/3rdparty/content-extractor/SiteConfig.php
vendored
@ -1,184 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Site Config
|
||||
*
|
||||
* Each instance of this class should hold extraction patterns and other directives
|
||||
* for a website. See ContentExtractor class to see how it's used.
|
||||
*
|
||||
* @version 0.6
|
||||
* @date 2011-10-30
|
||||
* @author Keyvan Minoukadeh
|
||||
* @copyright 2011 Keyvan Minoukadeh
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3
|
||||
*/
|
||||
|
||||
class SiteConfig
|
||||
{
|
||||
// Use first matching element as title (0 or more xpath expressions)
|
||||
public $title = array();
|
||||
|
||||
// Use first matching element as body (0 or more xpath expressions)
|
||||
public $body = array();
|
||||
|
||||
// Use first matching element as author (0 or more xpath expressions)
|
||||
public $author = array();
|
||||
|
||||
// Use first matching element as date (0 or more xpath expressions)
|
||||
public $date = array();
|
||||
|
||||
// Strip elements matching these xpath expressions (0 or more)
|
||||
public $strip = array();
|
||||
|
||||
// Strip elements which contain these strings (0 or more) in the id or class attribute
|
||||
public $strip_id_or_class = array();
|
||||
|
||||
// Strip images which contain these strings (0 or more) in the src attribute
|
||||
public $strip_image_src = array();
|
||||
|
||||
// Additional HTTP headers to send
|
||||
// NOT YET USED
|
||||
public $http_header = array();
|
||||
|
||||
// Process HTML with tidy before creating DOM
|
||||
public $tidy = true;
|
||||
|
||||
// Autodetect title/body if xpath expressions fail to produce results.
|
||||
// Note that this applies to title and body separately, ie.
|
||||
// * if we get a body match but no title match, this option will determine whether we autodetect title
|
||||
// * if neither match, this determines whether we autodetect title and body.
|
||||
// Also note that this only applies when there is at least one xpath expression in title or body, ie.
|
||||
// * if title and body are both empty (no xpath expressions), this option has no effect (both title and body will be auto-detected)
|
||||
// * if there's an xpath expression for title and none for body, body will be auto-detected and this option will determine whether we auto-detect title if the xpath expression for it fails to produce results.
|
||||
// Usage scenario: you want to extract something specific from a set of URLs, e.g. a table, and if the table is not found, you want to ignore the entry completely. Auto-detection is unlikely to succeed here, so you construct your patterns and set this option to false. Another scenario may be a site where auto-detection has proven to fail (or worse, picked up the wrong content).
|
||||
public $autodetect_on_failure = true;
|
||||
|
||||
// Clean up content block - attempt to remove elements that appear to be superfluous
|
||||
public $prune = true;
|
||||
|
||||
// Test URL - if present, can be used to test the config above
|
||||
public $test_url = null;
|
||||
|
||||
// Single-page link - should identify a link element or URL pointing to the page holding the entire article
|
||||
// This is useful for sites which split their articles across multiple pages. Links to such pages tend to
|
||||
// display the first page with links to the other pages at the bottom. Often there is also a link to a page
|
||||
// which displays the entire article on one page (e.g. 'print view').
|
||||
// This should be an XPath expression identifying the link to that page. If present and we find a match,
|
||||
// we will retrieve that page and the rest of the options in this config will be applied to the new page.
|
||||
public $single_page_link = array();
|
||||
|
||||
// Single-page link in feed? - same as above, but patterns applied to item description HTML taken from feed
|
||||
public $single_page_link_in_feed = array();
|
||||
|
||||
// TODO: which parser to use for turning raw HTML into a DOMDocument
|
||||
public $parser = 'libxml';
|
||||
|
||||
// String replacement to be made on HTML before processing begins
|
||||
public $replace_string = array();
|
||||
|
||||
// the options below cannot be set in the config files which this class represents
|
||||
|
||||
public static $debug = false;
|
||||
protected static $config_path;
|
||||
protected static $config_path_fallback;
|
||||
protected static $config_cache = array();
|
||||
const HOSTNAME_REGEX = '/^(([a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9-]*[A-Za-z0-9])$/';
|
||||
|
||||
protected static function debug($msg) {
|
||||
if (self::$debug) {
|
||||
$mem = round(memory_get_usage()/1024, 2);
|
||||
$memPeak = round(memory_get_peak_usage()/1024, 2);
|
||||
echo '* ',$msg;
|
||||
echo ' - mem used: ',$mem," (peak: $memPeak)\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public static function set_config_path($path, $fallback=null) {
|
||||
self::$config_path = $path;
|
||||
self::$config_path_fallback = $fallback;
|
||||
}
|
||||
|
||||
public static function add_to_cache($host, SiteConfig $config) {
|
||||
$host = strtolower($host);
|
||||
self::$config_cache[$host] = $config;
|
||||
}
|
||||
|
||||
// returns SiteConfig instance if an appropriate one is found, false otherwise
|
||||
public static function build($host) {
|
||||
$host = strtolower($host);
|
||||
if (substr($host, 0, 4) == 'www.') $host = substr($host, 4);
|
||||
if (!$host || (strlen($host) > 200) || !preg_match(self::HOSTNAME_REGEX, $host)) return false;
|
||||
// check for site configuration
|
||||
$try = array($host);
|
||||
$split = explode('.', $host);
|
||||
if (count($split) > 1) {
|
||||
array_shift($split);
|
||||
$try[] = '.'.implode('.', $split);
|
||||
}
|
||||
foreach ($try as $h) {
|
||||
if (array_key_exists($h, self::$config_cache)) {
|
||||
self::debug("... cached ($h)");
|
||||
return self::$config_cache[$h];
|
||||
} elseif (file_exists(self::$config_path."/$h.txt")) {
|
||||
self::debug("... from file ($h)");
|
||||
$file = self::$config_path."/$h.txt";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($file)) {
|
||||
if (isset(self::$config_path_fallback)) {
|
||||
self::debug("... trying fallback ($host)");
|
||||
foreach ($try as $h) {
|
||||
if (file_exists(self::$config_path_fallback."/$h.txt")) {
|
||||
self::debug("... from fallback file ($h)");
|
||||
$file = self::$config_path_fallback."/$h.txt";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isset($file)) {
|
||||
self::debug("... no match in fallback directory");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
self::debug("... no match ($host)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$config_file = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
if (!$config_file || !is_array($config_file)) return false;
|
||||
$config = new SiteConfig();
|
||||
foreach ($config_file as $line) {
|
||||
$line = trim($line);
|
||||
|
||||
// skip comments, empty lines
|
||||
if ($line == '' || $line[0] == '#') continue;
|
||||
|
||||
// get command
|
||||
$command = explode(':', $line, 2);
|
||||
// if there's no colon ':', skip this line
|
||||
if (count($command) != 2) continue;
|
||||
$val = trim($command[1]);
|
||||
$command = trim($command[0]);
|
||||
if ($command == '' || $val == '') continue;
|
||||
|
||||
// check for commands where we accept multiple statements
|
||||
if (in_array($command, array('title', 'body', 'author', 'date', 'strip', 'strip_id_or_class', 'strip_image_src', 'single_page_link', 'single_page_link_in_feed', 'http_header'))) {
|
||||
array_push($config->$command, $val);
|
||||
// check for single statement commands that evaluate to true or false
|
||||
} elseif (in_array($command, array('tidy', 'prune', 'autodetect_on_failure'))) {
|
||||
$config->$command = ($val == 'yes');
|
||||
// check for single statement commands stored as strings
|
||||
} elseif (in_array($command, array('test_url', 'parser'))) {
|
||||
$config->$command = $val;
|
||||
} elseif ((substr($command, -1) == ')') && preg_match('!^([a-z0-9_]+)\((.*?)\)$!i', $command, $match)) {
|
||||
if (in_array($match[1], array('replace_string'))) {
|
||||
$command = $match[1];
|
||||
array_push($config->$command, array($match[2], $val));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
?>
|
||||
24
inc/3rdparty/feedwriter/DummySingleItemFeed.php
vendored
24
inc/3rdparty/feedwriter/DummySingleItemFeed.php
vendored
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
// create single item dummy feed object
|
||||
class DummySingleItemFeed {
|
||||
public $item;
|
||||
function __construct($url) { $this->item = new DummySingleItem($url); }
|
||||
public function get_title() { return ''; }
|
||||
public function get_description() { return 'Content extracted from '.$this->item->url; }
|
||||
public function get_link() { return $this->item->url; }
|
||||
public function get_language() { return false; }
|
||||
public function get_image_url() { return false; }
|
||||
public function get_items($start=0, $max=1) { return array(0=>$this->item); }
|
||||
}
|
||||
class DummySingleItem {
|
||||
public $url;
|
||||
function __construct($url) { $this->url = $url; }
|
||||
public function get_permalink() { return $this->url; }
|
||||
public function get_title() { return ''; }
|
||||
public function get_date($format='') { return false; }
|
||||
public function get_author($key=0) { return null; }
|
||||
public function get_authors() { return null; }
|
||||
public function get_description() { return ''; }
|
||||
public function get_enclosure($key=0, $prefer=null) { return null; }
|
||||
public function get_enclosures() { return null; }
|
||||
}
|
||||
167
inc/3rdparty/feedwriter/FeedItem.php
vendored
167
inc/3rdparty/feedwriter/FeedItem.php
vendored
@ -1,167 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Univarsel Feed Writer
|
||||
*
|
||||
* FeedItem class - Used as feed element in FeedWriter class
|
||||
*
|
||||
* @package UnivarselFeedWriter
|
||||
* @author Anis uddin Ahmad <anisniit@gmail.com>
|
||||
* @link http://www.ajaxray.com/projects/rss
|
||||
*/
|
||||
class FeedItem
|
||||
{
|
||||
private $elements = array(); //Collection of feed elements
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param contant (RSS1/RSS2/ATOM) RSS2 is default.
|
||||
*/
|
||||
function __construct($version = RSS2)
|
||||
{
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to elements array
|
||||
*
|
||||
* @access public
|
||||
* @param srting The tag name of an element
|
||||
* @param srting The content of tag
|
||||
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
|
||||
* @return void
|
||||
*/
|
||||
public function addElement($elementName, $content, $attributes = null)
|
||||
{
|
||||
$this->elements[$elementName]['name'] = $elementName;
|
||||
$this->elements[$elementName]['content'] = $content;
|
||||
$this->elements[$elementName]['attributes'] = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set multiple feed elements from an array.
|
||||
* Elements which have attributes cannot be added by this method
|
||||
*
|
||||
* @access public
|
||||
* @param array array of elements in 'tagName' => 'tagContent' format.
|
||||
* @return void
|
||||
*/
|
||||
public function addElementArray($elementArray)
|
||||
{
|
||||
if(! is_array($elementArray)) return;
|
||||
foreach ($elementArray as $elementName => $content)
|
||||
{
|
||||
$this->addElement($elementName, $content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the collection of elements in this feed item
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getElements()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
// Wrapper functions ------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the 'dscription' element of feed item
|
||||
*
|
||||
* @access public
|
||||
* @param string The content of 'description' element
|
||||
* @return void
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$tag = ($this->version == ATOM)? 'summary' : 'description';
|
||||
$this->addElement($tag, $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Set the 'title' element of feed item
|
||||
* @access public
|
||||
* @param string The content of 'title' element
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->addElement('title', $title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'date' element of feed item
|
||||
*
|
||||
* @access public
|
||||
* @param string The content of 'date' element
|
||||
* @return void
|
||||
*/
|
||||
public function setDate($date)
|
||||
{
|
||||
if(! is_numeric($date))
|
||||
{
|
||||
$date = strtotime($date);
|
||||
}
|
||||
|
||||
if($this->version == ATOM)
|
||||
{
|
||||
$tag = 'updated';
|
||||
$value = date(DATE_ATOM, $date);
|
||||
}
|
||||
elseif($this->version == RSS2)
|
||||
{
|
||||
$tag = 'pubDate';
|
||||
$value = date(DATE_RSS, $date);
|
||||
}
|
||||
else
|
||||
{
|
||||
$tag = 'dc:date';
|
||||
$value = date("Y-m-d", $date);
|
||||
}
|
||||
|
||||
$this->addElement($tag, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'link' element of feed item
|
||||
*
|
||||
* @access public
|
||||
* @param string The content of 'link' element
|
||||
* @return void
|
||||
*/
|
||||
public function setLink($link)
|
||||
{
|
||||
if($this->version == RSS2 || $this->version == RSS1)
|
||||
{
|
||||
$this->addElement('link', $link);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->addElement('link','',array('href'=>$link));
|
||||
$this->addElement('id', FeedWriter::uuid($link,'urn:uuid:'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'encloser' element of feed item
|
||||
* For RSS 2.0 only
|
||||
*
|
||||
* @access public
|
||||
* @param string The url attribute of encloser tag
|
||||
* @param string The length attribute of encloser tag
|
||||
* @param string The type attribute of encloser tag
|
||||
* @return void
|
||||
*/
|
||||
public function setEncloser($url, $length, $type)
|
||||
{
|
||||
$attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type);
|
||||
$this->addElement('enclosure','',$attributes);
|
||||
}
|
||||
|
||||
} // end of class FeedItem
|
||||
?>
|
||||
434
inc/3rdparty/feedwriter/FeedWriter.php
vendored
434
inc/3rdparty/feedwriter/FeedWriter.php
vendored
@ -1,434 +0,0 @@
|
||||
<?php
|
||||
define('RSS2', 1, true);
|
||||
define('JSON', 2, true);
|
||||
define('ATOM', 3, true);
|
||||
|
||||
/**
|
||||
* Univarsel Feed Writer class
|
||||
*
|
||||
* Genarate RSS2 or JSON (original: RSS 1.0, RSS2.0 and ATOM Feed)
|
||||
*
|
||||
* Modified for FiveFilters.org's Full-Text RSS project
|
||||
* to allow for inclusion of hubs, JSON output.
|
||||
* Stripped RSS1 and ATOM support.
|
||||
*
|
||||
* @package UnivarselFeedWriter
|
||||
* @author Anis uddin Ahmad <anisniit@gmail.com>
|
||||
* @link http://www.ajaxray.com/projects/rss
|
||||
*/
|
||||
class FeedWriter
|
||||
{
|
||||
private $self = null; // self URL - http://feed2.w3.org/docs/warning/MissingAtomSelfLink.html
|
||||
private $hubs = array(); // PubSubHubbub hubs
|
||||
private $channels = array(); // Collection of channel elements
|
||||
private $items = array(); // Collection of items as object of FeedItem class.
|
||||
private $data = array(); // Store some other version wise data
|
||||
private $CDATAEncoding = array(); // The tag names which have to encoded as CDATA
|
||||
private $xsl = null; // stylesheet to render RSS (used by Chrome)
|
||||
private $json = null; // JSON object
|
||||
|
||||
private $version = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param constant the version constant (RSS2 or JSON).
|
||||
*/
|
||||
function __construct($version = RSS2)
|
||||
{
|
||||
$this->version = $version;
|
||||
|
||||
// Setting default value for assential channel elements
|
||||
$this->channels['title'] = $version . ' Feed';
|
||||
$this->channels['link'] = 'http://www.ajaxray.com/blog';
|
||||
|
||||
//Tag names to encode in CDATA
|
||||
$this->CDATAEncoding = array('description', 'content:encoded', 'content', 'subtitle', 'summary');
|
||||
}
|
||||
|
||||
public function setFormat($format) {
|
||||
$this->version = $format;
|
||||
}
|
||||
|
||||
// Start # public functions ---------------------------------------------
|
||||
|
||||
/**
|
||||
* Set a channel element
|
||||
* @access public
|
||||
* @param srting name of the channel tag
|
||||
* @param string content of the channel tag
|
||||
* @return void
|
||||
*/
|
||||
public function setChannelElement($elementName, $content)
|
||||
{
|
||||
$this->channels[$elementName] = $content ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set multiple channel elements from an array. Array elements
|
||||
* should be 'channelName' => 'channelContent' format.
|
||||
*
|
||||
* @access public
|
||||
* @param array array of channels
|
||||
* @return void
|
||||
*/
|
||||
public function setChannelElementsFromArray($elementArray)
|
||||
{
|
||||
if(! is_array($elementArray)) return;
|
||||
foreach ($elementArray as $elementName => $content)
|
||||
{
|
||||
$this->setChannelElement($elementName, $content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Genarate the actual RSS/JSON file
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function genarateFeed()
|
||||
{
|
||||
if ($this->version == RSS2) {
|
||||
header('Content-type: text/xml; charset=UTF-8');
|
||||
} elseif ($this->version == JSON) {
|
||||
header('Content-type: application/json; charset=UTF-8');
|
||||
$this->json = new stdClass();
|
||||
}
|
||||
$this->printHead();
|
||||
$this->printChannels();
|
||||
$this->printItems();
|
||||
$this->printTale();
|
||||
if ($this->version == JSON) {
|
||||
echo json_encode($this->json);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FeedItem.
|
||||
*
|
||||
* @access public
|
||||
* @return object instance of FeedItem class
|
||||
*/
|
||||
public function createNewItem()
|
||||
{
|
||||
$Item = new FeedItem($this->version);
|
||||
return $Item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a FeedItem to the main class
|
||||
*
|
||||
* @access public
|
||||
* @param object instance of FeedItem class
|
||||
* @return void
|
||||
*/
|
||||
public function addItem($feedItem)
|
||||
{
|
||||
$this->items[] = $feedItem;
|
||||
}
|
||||
|
||||
// Wrapper functions -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the 'title' channel element
|
||||
*
|
||||
* @access public
|
||||
* @param srting value of 'title' channel tag
|
||||
* @return void
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->setChannelElement('title', $title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a hub to the channel element
|
||||
*
|
||||
* @access public
|
||||
* @param string URL
|
||||
* @return void
|
||||
*/
|
||||
public function addHub($hub)
|
||||
{
|
||||
$this->hubs[] = $hub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set XSL URL
|
||||
*
|
||||
* @access public
|
||||
* @param string URL
|
||||
* @return void
|
||||
*/
|
||||
public function setXsl($xsl)
|
||||
{
|
||||
$this->xsl = $xsl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set self URL
|
||||
*
|
||||
* @access public
|
||||
* @param string URL
|
||||
* @return void
|
||||
*/
|
||||
public function setSelf($self)
|
||||
{
|
||||
$this->self = $self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'description' channel element
|
||||
*
|
||||
* @access public
|
||||
* @param srting value of 'description' channel tag
|
||||
* @return void
|
||||
*/
|
||||
public function setDescription($desciption)
|
||||
{
|
||||
$tag = ($this->version == ATOM)? 'subtitle' : 'description';
|
||||
$this->setChannelElement($tag, $desciption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'link' channel element
|
||||
*
|
||||
* @access public
|
||||
* @param srting value of 'link' channel tag
|
||||
* @return void
|
||||
*/
|
||||
public function setLink($link)
|
||||
{
|
||||
$this->setChannelElement('link', $link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'image' channel element
|
||||
*
|
||||
* @access public
|
||||
* @param srting title of image
|
||||
* @param srting link url of the imahe
|
||||
* @param srting path url of the image
|
||||
* @return void
|
||||
*/
|
||||
public function setImage($title, $link, $url)
|
||||
{
|
||||
$this->setChannelElement('image', array('title'=>$title, 'link'=>$link, 'url'=>$url));
|
||||
}
|
||||
|
||||
// End # public functions ----------------------------------------------
|
||||
|
||||
// Start # private functions ----------------------------------------------
|
||||
|
||||
/**
|
||||
* Prints the xml and rss namespace
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function printHead()
|
||||
{
|
||||
if ($this->version == RSS2)
|
||||
{
|
||||
$out = '<?xml version="1.0" encoding="utf-8"?>'."\n";
|
||||
if ($this->xsl) $out .= '<?xml-stylesheet type="text/xsl" href="'.htmlspecialchars($this->xsl).'"?>' . PHP_EOL;
|
||||
$out .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">' . PHP_EOL;
|
||||
echo $out;
|
||||
}
|
||||
elseif ($this->version == JSON)
|
||||
{
|
||||
$this->json->rss = array('@attributes' => array('version' => '2.0'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the open tags at the end of file
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function printTale()
|
||||
{
|
||||
if ($this->version == RSS2)
|
||||
{
|
||||
echo '</channel>',PHP_EOL,'</rss>';
|
||||
}
|
||||
// do nothing for JSON
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single node as xml format
|
||||
*
|
||||
* @access private
|
||||
* @param string name of the tag
|
||||
* @param mixed tag value as string or array of nested tags in 'tagName' => 'tagValue' format
|
||||
* @param array Attributes(if any) in 'attrName' => 'attrValue' format
|
||||
* @return string formatted xml tag
|
||||
*/
|
||||
private function makeNode($tagName, $tagContent, $attributes = null)
|
||||
{
|
||||
if ($this->version == RSS2)
|
||||
{
|
||||
$nodeText = '';
|
||||
$attrText = '';
|
||||
if (is_array($attributes))
|
||||
{
|
||||
foreach ($attributes as $key => $value)
|
||||
{
|
||||
$attrText .= " $key=\"$value\" ";
|
||||
}
|
||||
}
|
||||
$nodeText .= "<{$tagName}{$attrText}>";
|
||||
if (is_array($tagContent))
|
||||
{
|
||||
foreach ($tagContent as $key => $value)
|
||||
{
|
||||
$nodeText .= $this->makeNode($key, $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? $tagContent : htmlentities($tagContent);
|
||||
$nodeText .= htmlspecialchars($tagContent);
|
||||
}
|
||||
//$nodeText .= (in_array($tagName, $this->CDATAEncoding))? "]]></$tagName>" : "</$tagName>";
|
||||
$nodeText .= "</$tagName>";
|
||||
return $nodeText . PHP_EOL;
|
||||
}
|
||||
elseif ($this->version == JSON)
|
||||
{
|
||||
$tagName = (string)$tagName;
|
||||
$tagName = strtr($tagName, ':', '_');
|
||||
$node = null;
|
||||
if (!$tagContent && is_array($attributes) && count($attributes))
|
||||
{
|
||||
$node = array('@attributes' => $this->json_keys($attributes));
|
||||
} else {
|
||||
if (is_array($tagContent)) {
|
||||
$node = $this->json_keys($tagContent);
|
||||
} else {
|
||||
$node = $tagContent;
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
return ''; // should not get here
|
||||
}
|
||||
|
||||
private function json_keys(array $array) {
|
||||
$new = array();
|
||||
foreach ($array as $key => $val) {
|
||||
if (is_string($key)) $key = strtr($key, ':', '_');
|
||||
if (is_array($val)) {
|
||||
$new[$key] = $this->json_keys($val);
|
||||
} else {
|
||||
$new[$key] = $val;
|
||||
}
|
||||
}
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Print channels
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function printChannels()
|
||||
{
|
||||
//Start channel tag
|
||||
switch ($this->version)
|
||||
{
|
||||
case RSS2:
|
||||
echo '<channel>' . PHP_EOL;
|
||||
// add hubs
|
||||
foreach ($this->hubs as $hub) {
|
||||
//echo $this->makeNode('link', '', array('rel'=>'hub', 'href'=>$hub, 'xmlns'=>'http://www.w3.org/2005/Atom'));
|
||||
echo '<link rel="hub" href="'.htmlspecialchars($hub).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
|
||||
}
|
||||
// add self
|
||||
if (isset($this->self)) {
|
||||
//echo $this->makeNode('link', '', array('rel'=>'self', 'href'=>$this->self, 'xmlns'=>'http://www.w3.org/2005/Atom'));
|
||||
echo '<link rel="self" href="'.htmlspecialchars($this->self).'" xmlns="http://www.w3.org/2005/Atom" />' . PHP_EOL;
|
||||
}
|
||||
//Print Items of channel
|
||||
foreach ($this->channels as $key => $value)
|
||||
{
|
||||
echo $this->makeNode($key, $value);
|
||||
}
|
||||
break;
|
||||
case JSON:
|
||||
$this->json->rss['channel'] = (object)$this->json_keys($this->channels);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints formatted feed items
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function printItems()
|
||||
{
|
||||
foreach ($this->items as $item)
|
||||
{
|
||||
$thisItems = $item->getElements();
|
||||
|
||||
echo $this->startItem();
|
||||
|
||||
if ($this->version == JSON) {
|
||||
$json_item = array();
|
||||
}
|
||||
|
||||
foreach ($thisItems as $feedItem )
|
||||
{
|
||||
if ($this->version == RSS2) {
|
||||
echo $this->makeNode($feedItem['name'], $feedItem['content'], $feedItem['attributes']);
|
||||
} elseif ($this->version == JSON) {
|
||||
$json_item[strtr($feedItem['name'], ':', '_')] = $this->makeNode($feedItem['name'], $feedItem['content'], $feedItem['attributes']);
|
||||
}
|
||||
}
|
||||
echo $this->endItem();
|
||||
if ($this->version == JSON) {
|
||||
if (count($this->items) > 1) {
|
||||
$this->json->rss['channel']->item[] = $json_item;
|
||||
} else {
|
||||
$this->json->rss['channel']->item = $json_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the starting tag of channels
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function startItem()
|
||||
{
|
||||
if ($this->version == RSS2)
|
||||
{
|
||||
echo '<item>' . PHP_EOL;
|
||||
}
|
||||
// nothing for JSON
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes feed item tag
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function endItem()
|
||||
{
|
||||
if ($this->version == RSS2)
|
||||
{
|
||||
echo '</item>' . PHP_EOL;
|
||||
}
|
||||
// nothing for JSON
|
||||
}
|
||||
|
||||
// End # private functions ----------------------------------------------
|
||||
}
|
||||
404
inc/3rdparty/humble-http-agent/CookieJar.php
vendored
404
inc/3rdparty/humble-http-agent/CookieJar.php
vendored
@ -1,404 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Cookie Jar
|
||||
*
|
||||
* PHP class for handling cookies, as defined by the Netscape spec:
|
||||
* <http://curl.haxx.se/rfc/cookie_spec.html>
|
||||
*
|
||||
* This class should be used to handle cookies (storing cookies from HTTP response messages, and
|
||||
* sending out cookies in HTTP request messages). This has been adapted for FiveFilters.org
|
||||
* from the original version used in HTTP Navigator. See http://www.keyvan.net/code/http-navigator/
|
||||
*
|
||||
* This class is mainly based on Cookies.pm <http://search.cpan.org/author/GAAS/libwww-perl-5.65/
|
||||
* lib/HTTP/Cookies.pm> from the libwww-perl collection <http://www.linpro.no/lwp/>.
|
||||
* Unlike Cookies.pm, this class only supports the Netscape cookie spec, not RFC 2965.
|
||||
*
|
||||
* @version 0.5
|
||||
* @date 2011-03-15
|
||||
* @see http://php.net/HttpRequestPool
|
||||
* @author Keyvan Minoukadeh
|
||||
* @copyright 2011 Keyvan Minoukadeh
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3
|
||||
*/
|
||||
|
||||
class CookieJar
|
||||
{
|
||||
/**
|
||||
* Cookies - array containing all cookies.
|
||||
*
|
||||
* <pre>
|
||||
* Cookies are stored like this:
|
||||
* [domain][path][name] = array
|
||||
* where array is:
|
||||
* 0 => value, 1 => secure, 2 => expires
|
||||
* </pre>
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
public $cookies = array();
|
||||
public $debug = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
protected function debug($msg, $file=null, $line=null) {
|
||||
if ($this->debug) {
|
||||
$mem = round(memory_get_usage()/1024, 2);
|
||||
$memPeak = round(memory_get_peak_usage()/1024, 2);
|
||||
echo '* ',$msg;
|
||||
if (isset($file, $line)) echo " ($file line $line)";
|
||||
echo ' - mem used: ',$mem," (peak: $memPeak)\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get matching cookies
|
||||
*
|
||||
* Only use this method if you cannot use add_cookie_header(), for example, if you want to use
|
||||
* this cookie jar class without using the request class.
|
||||
*
|
||||
* @param array $param associative array containing 'domain', 'path', 'secure' keys
|
||||
* @return string
|
||||
* @see add_cookie_header()
|
||||
*/
|
||||
public function getMatchingCookies($url)
|
||||
{
|
||||
if (($parts = @parse_url($url)) && isset($parts['scheme'], $parts['host'], $parts['path'])) {
|
||||
$param['domain'] = $parts['host'];
|
||||
$param['path'] = $parts['path'];
|
||||
$param['secure'] = (strtolower($parts['scheme']) == 'https');
|
||||
unset($parts);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// RFC 2965 notes:
|
||||
// If multiple cookies satisfy the criteria above, they are ordered in
|
||||
// the Cookie header such that those with more specific Path attributes
|
||||
// precede those with less specific. Ordering with respect to other
|
||||
// attributes (e.g., Domain) is unspecified.
|
||||
$domain = $param['domain'];
|
||||
if (strpos($domain, '.') === false) $domain .= '.local';
|
||||
$request_path = $param['path'];
|
||||
if ($request_path == '') $request_path = '/';
|
||||
$request_secure = $param['secure'];
|
||||
$now = time();
|
||||
$matched_cookies = array();
|
||||
// domain - find matching domains
|
||||
$this->debug('Finding matching domains for '.$domain, __FILE__, __LINE__);
|
||||
while (strpos($domain, '.') !== false) {
|
||||
if (isset($this->cookies[$domain])) {
|
||||
$this->debug(' domain match found: '.$domain);
|
||||
$cookies =& $this->cookies[$domain];
|
||||
} else {
|
||||
$domain = $this->_reduce_domain($domain);
|
||||
continue;
|
||||
}
|
||||
// paths - find matching paths starting from most specific
|
||||
$this->debug(' - Finding matching paths for '.$request_path);
|
||||
$paths = array_keys($cookies);
|
||||
usort($paths, array($this, '_cmp_length'));
|
||||
foreach ($paths as $path) {
|
||||
// continue to next cookie if request path does not path-match cookie path
|
||||
if (!$this->_path_match($request_path, $path)) continue;
|
||||
// loop through cookie names
|
||||
$this->debug(' path match found: '.$path);
|
||||
foreach ($cookies[$path] as $name => $values) {
|
||||
// if this cookie is secure but request isn't, continue to next cookie
|
||||
if ($values[1] && !$request_secure) continue;
|
||||
// if cookie is not a session cookie and has expired, continue to next cookie
|
||||
if (is_int($values[2]) && ($values[2] < $now)) continue;
|
||||
// cookie matches request
|
||||
$this->debug(' cookie match: '.$name.'='.$values[0]);
|
||||
$matched_cookies[] = $name.'='.$values[0];
|
||||
}
|
||||
}
|
||||
$domain = $this->_reduce_domain($domain);
|
||||
}
|
||||
// return cookies
|
||||
return implode('; ', $matched_cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Set-Cookie values.
|
||||
*
|
||||
* Only use this method if you cannot use extract_cookies(), for example, if you want to use
|
||||
* this cookie jar class without using the response class.
|
||||
*
|
||||
* @param array $set_cookies array holding 1 or more "Set-Cookie" header values
|
||||
* @param array $param associative array containing 'host', 'path' keys
|
||||
* @return void
|
||||
* @see extract_cookies()
|
||||
*/
|
||||
public function storeCookies($url, $set_cookies)
|
||||
{
|
||||
if (count($set_cookies) == 0) return;
|
||||
$param = @parse_url($url);
|
||||
if (!is_array($param) || !isset($param['host'])) return;
|
||||
$request_host = $param['host'];
|
||||
if (strpos($request_host, '.') === false) $request_host .= '.local';
|
||||
$request_path = @$param['path'];
|
||||
if ($request_path == '') $request_path = '/';
|
||||
//
|
||||
// loop through set-cookie headers
|
||||
//
|
||||
foreach ($set_cookies as $set_cookie) {
|
||||
$this->debug('Parsing: '.$set_cookie);
|
||||
// temporary cookie store (before adding to jar)
|
||||
$tmp_cookie = array();
|
||||
$param = explode(';', $set_cookie);
|
||||
// loop through params
|
||||
for ($x=0; $x<count($param); $x++) {
|
||||
$key_val = explode('=', $param[$x], 2);
|
||||
if (count($key_val) != 2) {
|
||||
// if the first param isn't a name=value pair, continue to the next set-cookie
|
||||
// header
|
||||
if ($x == 0) continue 2;
|
||||
// check for secure flag
|
||||
if (strtolower(trim($key_val[0])) == 'secure') $tmp_cookie['secure'] = true;
|
||||
// continue to next param
|
||||
continue;
|
||||
}
|
||||
list($key, $val) = array_map('trim', $key_val);
|
||||
// first name=value pair is the cookie name and value
|
||||
// the name and value are stored under 'name' and 'value' to avoid conflicts
|
||||
// with later parameters.
|
||||
if ($x == 0) {
|
||||
$tmp_cookie = array('name'=>$key, 'value'=>$val);
|
||||
continue;
|
||||
}
|
||||
$key = strtolower($key);
|
||||
if (in_array($key, array('expires', 'path', 'domain', 'secure'))) {
|
||||
$tmp_cookie[$key] = $val;
|
||||
}
|
||||
}
|
||||
//
|
||||
// set cookie
|
||||
//
|
||||
// check domain
|
||||
if (isset($tmp_cookie['domain']) && ($tmp_cookie['domain'] != $request_host) &&
|
||||
($tmp_cookie['domain'] != ".$request_host")) {
|
||||
$domain = $tmp_cookie['domain'];
|
||||
if ((strpos($domain, '.') === false) && ($domain != 'local')) {
|
||||
$this->debug(' - domain "'.$domain.'" has no dot and is not a local domain');
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/\.[0-9]+$/', $domain)) {
|
||||
$this->debug(' - domain "'.$domain.'" appears to be an ip address');
|
||||
continue;
|
||||
}
|
||||
if (substr($domain, 0, 1) != '.') $domain = ".$domain";
|
||||
if (!$this->_domain_match($request_host, $domain)) {
|
||||
$this->debug(' - request host "'.$request_host.'" does not domain-match "'.$domain.'"');
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// if domain is not specified in the set-cookie header, domain will default to
|
||||
// the request host
|
||||
$domain = $request_host;
|
||||
}
|
||||
// check path
|
||||
if (isset($tmp_cookie['path']) && ($tmp_cookie['path'] != '')) {
|
||||
$path = urldecode($tmp_cookie['path']);
|
||||
if (!$this->_path_match($request_path, $path)) {
|
||||
$this->debug(' - request path "'.$request_path.'" does not path-match "'.$path.'"');
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$path = $request_path;
|
||||
$path = substr($path, 0, strrpos($path, '/'));
|
||||
if ($path == '') $path = '/';
|
||||
}
|
||||
// check if secure
|
||||
$secure = (isset($tmp_cookie['secure'])) ? true : false;
|
||||
// check expiry
|
||||
if (isset($tmp_cookie['expires'])) {
|
||||
if (($expires = strtotime($tmp_cookie['expires'])) < 0) {
|
||||
$expires = null;
|
||||
}
|
||||
} else {
|
||||
$expires = null;
|
||||
}
|
||||
// set cookie
|
||||
$this->set_cookie($domain, $path, $tmp_cookie['name'], $tmp_cookie['value'], $secure, $expires);
|
||||
}
|
||||
}
|
||||
|
||||
// return array of set-cookie values extracted from HTTP response headers (string $h)
|
||||
public function extractCookies($h) {
|
||||
$x = 0;
|
||||
$lines = 0;
|
||||
$headers = array();
|
||||
$last_match = false;
|
||||
$h = explode("\n", $h);
|
||||
foreach ($h as $line) {
|
||||
$line = rtrim($line);
|
||||
$lines++;
|
||||
|
||||
$trimmed_line = trim($line);
|
||||
if (isset($line_last)) {
|
||||
// check if we have \r\n\r\n (indicating the end of headers)
|
||||
// some servers will not use CRLF (\r\n), so we make CR (\r) optional.
|
||||
// if (preg_match('/\015?\012\015?\012/', $line_last.$line)) {
|
||||
// break;
|
||||
// }
|
||||
// As an alternative, we can check if the current trimmed line is empty
|
||||
if ($trimmed_line == '') {
|
||||
break;
|
||||
}
|
||||
|
||||
// check for continuation line...
|
||||
// RFC 2616 Section 2.2 "Basic Rules":
|
||||
// HTTP/1.1 header field values can be folded onto multiple lines if the
|
||||
// continuation line begins with a space or horizontal tab. All linear
|
||||
// white space, including folding, has the same semantics as SP. A
|
||||
// recipient MAY replace any linear white space with a single SP before
|
||||
// interpreting the field value or forwarding the message downstream.
|
||||
if ($last_match && preg_match('/^\s+(.*)/', $line, $match)) {
|
||||
// append to previous header value
|
||||
$headers[$x-1] .= ' '.rtrim($match[1]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$line_last = $line;
|
||||
|
||||
// split header name and value
|
||||
if (preg_match('/^Set-Cookie\s*:\s*(.*)/i', $line, $match)) {
|
||||
$headers[$x++] = rtrim($match[1]);
|
||||
$last_match = true;
|
||||
} else {
|
||||
$last_match = false;
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Cookie
|
||||
* @param string $domain
|
||||
* @param string $path
|
||||
* @param string $name cookie name
|
||||
* @param string $value cookie value
|
||||
* @param bool $secure
|
||||
* @param int $expires expiry time (null if session cookie, <= 0 will delete cookie)
|
||||
* @return void
|
||||
*/
|
||||
function set_cookie($domain, $path, $name, $value, $secure=false, $expires=null)
|
||||
{
|
||||
if ($domain == '') return;
|
||||
if ($path == '') return;
|
||||
if ($name == '') return;
|
||||
// check if cookie needs to go
|
||||
if (isset($expires) && ($expires <= 0)) {
|
||||
if (isset($this->cookies[$domain][$path][$name])) unset($this->cookies[$domain][$path][$name]);
|
||||
return;
|
||||
}
|
||||
if ($value == '') return;
|
||||
$this->cookies[$domain][$path][$name] = array($value, $secure, $expires);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cookies - [domain [,path [,name]]] - call method with no arguments to clear all cookies.
|
||||
* @param string $domain
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function clear($domain=null, $path=null, $name=null)
|
||||
{
|
||||
if (!isset($domain)) {
|
||||
$this->cookies = array();
|
||||
} elseif (!isset($path)) {
|
||||
if (isset($this->cookies[$domain])) unset($this->cookies[$domain]);
|
||||
} elseif (!isset($name)) {
|
||||
if (isset($this->cookies[$domain][$path])) unset($this->cookies[$domain][$path]);
|
||||
} elseif (isset($name)) {
|
||||
if (isset($this->cookies[$domain][$path][$name])) unset($this->cookies[$domain][$path][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare string length - used for sorting
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
function _cmp_length($a, $b)
|
||||
{
|
||||
$la = strlen($a); $lb = strlen($b);
|
||||
if ($la == $lb) return 0;
|
||||
return ($la > $lb) ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce domain
|
||||
* @param string $domain
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _reduce_domain($domain)
|
||||
{
|
||||
if ($domain == '') return '';
|
||||
if (substr($domain, 0, 1) == '.') return substr($domain, 1);
|
||||
return substr($domain, strpos($domain, '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Path match - check if path1 path-matches path2
|
||||
*
|
||||
* From RFC 2965:
|
||||
* <i>For two strings that represent paths, P1 and P2, P1 path-matches P2
|
||||
* if P2 is a prefix of P1 (including the case where P1 and P2 string-
|
||||
* compare equal). Thus, the string /tec/waldo path-matches /tec.</i>
|
||||
* @param string $path1
|
||||
* @param string $path2
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _path_match($path1, $path2)
|
||||
{
|
||||
return (substr($path1, 0, strlen($path2)) == $path2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Domain match - check if domain1 domain-matches domain2
|
||||
*
|
||||
* A few extracts from RFC 2965:
|
||||
* - A Set-Cookie2 from request-host y.x.foo.com for Domain=.foo.com
|
||||
* would be rejected, because H is y.x and contains a dot.
|
||||
*
|
||||
* - A Set-Cookie2 from request-host x.foo.com for Domain=.foo.com
|
||||
* would be accepted.
|
||||
*
|
||||
* - A Set-Cookie2 with Domain=.com or Domain=.com., will always be
|
||||
* rejected, because there is no embedded dot.
|
||||
*
|
||||
* - A Set-Cookie2 from request-host example for Domain=.local will
|
||||
* be accepted, because the effective host name for the request-
|
||||
* host is example.local, and example.local domain-matches .local.
|
||||
*
|
||||
* I'm ignoring the first point for now (must check to see how other browsers handle
|
||||
* this rule for Set-Cookie headers)
|
||||
*
|
||||
* @param string $domain1
|
||||
* @param string $domain2
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _domain_match($domain1, $domain2)
|
||||
{
|
||||
$domain1 = strtolower($domain1);
|
||||
$domain2 = strtolower($domain2);
|
||||
while (strpos($domain1, '.') !== false) {
|
||||
if ($domain1 == $domain2) return true;
|
||||
$domain1 = $this->_reduce_domain($domain1);
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
720
inc/3rdparty/humble-http-agent/HumbleHttpAgent.php
vendored
720
inc/3rdparty/humble-http-agent/HumbleHttpAgent.php
vendored
@ -1,720 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Humble HTTP Agent
|
||||
*
|
||||
* This class is designed to take advantage of parallel HTTP requests
|
||||
* offered by PHP's PECL HTTP extension or the curl_multi_* functions.
|
||||
* For environments which do not have these options, it reverts to standard sequential
|
||||
* requests (using file_get_contents())
|
||||
*
|
||||
* @version 1.0
|
||||
* @date 2012-02-09
|
||||
* @see http://php.net/HttpRequestPool
|
||||
* @author Keyvan Minoukadeh
|
||||
* @copyright 2011-2012 Keyvan Minoukadeh
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0.html AGPL v3
|
||||
*/
|
||||
|
||||
class HumbleHttpAgent
|
||||
{
|
||||
const METHOD_REQUEST_POOL = 1;
|
||||
const METHOD_CURL_MULTI = 2;
|
||||
const METHOD_FILE_GET_CONTENTS = 4;
|
||||
//const UA_BROWSER = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1';
|
||||
const UA_BROWSER = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.92 Safari/535.2';
|
||||
const UA_PHP = 'PHP/5.2';
|
||||
const REF_GOOGLE = 'http://www.google.co.uk/url?sa=t&source=web&cd=1';
|
||||
|
||||
protected $requests = array();
|
||||
protected $redirectQueue = array();
|
||||
protected $requestOptions;
|
||||
protected $maxParallelRequests = 5;
|
||||
protected $cache = null; //TODO
|
||||
protected $httpContext;
|
||||
protected $minimiseMemoryUse = false; //TODO
|
||||
protected $debug = false;
|
||||
protected $method;
|
||||
protected $cookieJar;
|
||||
public $rewriteHashbangFragment = true; // see http://code.google.com/web/ajaxcrawling/docs/specification.html
|
||||
public $maxRedirects = 5;
|
||||
public $userAgentMap = array();
|
||||
public $rewriteUrls = array();
|
||||
public $userAgentDefault;
|
||||
public $referer;
|
||||
//public $userAgent = 'Mozilla/5.0';
|
||||
|
||||
// Prevent certain file/mime types
|
||||
// HTTP responses which match these content types will
|
||||
// be returned without body.
|
||||
public $headerOnlyTypes = array();
|
||||
// URLs ending with one of these extensions will
|
||||
// prompt Humble HTTP Agent to send a HEAD request first
|
||||
// to see if returned content type matches $headerOnlyTypes.
|
||||
public $headerOnlyClues = array('pdf','mp3','zip','exe','gif','gzip','gz','jpeg','jpg','mpg','mpeg','png','ppt','mov');
|
||||
|
||||
//TODO: set max file size
|
||||
//TODO: normalise headers
|
||||
|
||||
function __construct($requestOptions=null, $method=null) {
|
||||
$this->userAgentDefault = self::UA_BROWSER;
|
||||
$this->referer = self::REF_GOOGLE;
|
||||
// set the request method
|
||||
if (in_array($method, array(1,2,4))) {
|
||||
$this->method = $method;
|
||||
} else {
|
||||
if (class_exists('HttpRequestPool')) {
|
||||
$this->method = self::METHOD_REQUEST_POOL;
|
||||
} elseif (function_exists('curl_multi_init')) {
|
||||
$this->method = self::METHOD_CURL_MULTI;
|
||||
} else {
|
||||
$this->method = self::METHOD_FILE_GET_CONTENTS;
|
||||
}
|
||||
}
|
||||
if ($this->method == self::METHOD_CURL_MULTI) {
|
||||
require_once(dirname(__FILE__).'/RollingCurl.php');
|
||||
}
|
||||
// create cookie jar
|
||||
$this->cookieJar = new CookieJar();
|
||||
// set request options (redirect must be 0)
|
||||
$this->requestOptions = array(
|
||||
'timeout' => 15,
|
||||
'redirect' => 0 // we handle redirects manually so we can rewrite the new hashbang URLs that are creeping up over the web
|
||||
// TODO: test onprogress?
|
||||
);
|
||||
if (is_array($requestOptions)) {
|
||||
$this->requestOptions = array_merge($this->requestOptions, $requestOptions);
|
||||
}
|
||||
$this->httpContext = array(
|
||||
'http' => array(
|
||||
'ignore_errors' => true,
|
||||
'timeout' => $this->requestOptions['timeout'],
|
||||
'max_redirects' => $this->requestOptions['redirect'],
|
||||
'header' => "Accept: */*\r\n"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function debug($msg) {
|
||||
if ($this->debug) {
|
||||
$mem = round(memory_get_usage()/1024, 2);
|
||||
$memPeak = round(memory_get_peak_usage()/1024, 2);
|
||||
echo '* ',$msg;
|
||||
echo ' - mem used: ',$mem," (peak: $memPeak)\n";
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getUserAgent($url, $asArray=false) {
|
||||
$host = @parse_url($url, PHP_URL_HOST);
|
||||
if (strtolower(substr($host, 0, 4)) == 'www.') {
|
||||
$host = substr($host, 4);
|
||||
}
|
||||
if ($host) {
|
||||
$try = array($host);
|
||||
$split = explode('.', $host);
|
||||
if (count($split) > 1) {
|
||||
array_shift($split);
|
||||
$try[] = '.'.implode('.', $split);
|
||||
}
|
||||
foreach ($try as $h) {
|
||||
if (isset($this->userAgentMap[$h])) {
|
||||
$ua = $this->userAgentMap[$h];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($ua)) $ua = $this->userAgentDefault;
|
||||
if ($asArray) {
|
||||
return array('User-Agent' => $ua);
|
||||
} else {
|
||||
return 'User-Agent: '.$ua;
|
||||
}
|
||||
}
|
||||
|
||||
public function rewriteHashbangFragment($url) {
|
||||
// return $url if there's no '#!'
|
||||
if (strpos($url, '#!') === false) return $url;
|
||||
// split $url and rewrite
|
||||
// TODO: is SimplePie_IRI included?
|
||||
$iri = new SimplePie_IRI($url);
|
||||
$fragment = substr($iri->fragment, 1); // strip '!'
|
||||
$iri->fragment = null;
|
||||
if (isset($iri->query)) {
|
||||
parse_str($iri->query, $query);
|
||||
} else {
|
||||
$query = array();
|
||||
}
|
||||
$query['_escaped_fragment_'] = (string)$fragment;
|
||||
$iri->query = str_replace('%2F', '/', http_build_query($query)); // needed for some sites
|
||||
return $iri->get_iri();
|
||||
}
|
||||
|
||||
public function removeFragment($url) {
|
||||
$pos = strpos($url, '#');
|
||||
if ($pos === false) {
|
||||
return $url;
|
||||
} else {
|
||||
return substr($url, 0, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
public function rewriteUrls($url) {
|
||||
foreach ($this->rewriteUrls as $find => $action) {
|
||||
if (strpos($url, $find) !== false) {
|
||||
if (is_array($action)) {
|
||||
return strtr($url, $action);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function enableDebug($bool=true) {
|
||||
$this->debug = (bool)$bool;
|
||||
}
|
||||
|
||||
public function minimiseMemoryUse($bool = true) {
|
||||
$this->minimiseMemoryUse = $bool;
|
||||
}
|
||||
|
||||
public function setMaxParallelRequests($max) {
|
||||
$this->maxParallelRequests = $max;
|
||||
}
|
||||
|
||||
public function validateUrl($url) {
|
||||
$url = filter_var($url, FILTER_SANITIZE_URL);
|
||||
$test = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED);
|
||||
// deal with bug http://bugs.php.net/51192 (present in PHP 5.2.13 and PHP 5.3.2)
|
||||
if ($test === false) {
|
||||
$test = filter_var(strtr($url, '-', '_'), FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED);
|
||||
}
|
||||
if ($test !== false && $test !== null && preg_match('!^https?://!', $url)) {
|
||||
return $url;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchAll(array $urls) {
|
||||
$this->fetchAllOnce($urls, $isRedirect=false);
|
||||
$redirects = 0;
|
||||
while (!empty($this->redirectQueue) && ++$redirects <= $this->maxRedirects) {
|
||||
$this->debug("Following redirects #$redirects...");
|
||||
$this->fetchAllOnce($this->redirectQueue, $isRedirect=true);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch all URLs without following redirects
|
||||
public function fetchAllOnce(array $urls, $isRedirect=false) {
|
||||
if (!$isRedirect) $urls = array_unique($urls);
|
||||
if (empty($urls)) return;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// parallel (HttpRequestPool)
|
||||
if ($this->method == self::METHOD_REQUEST_POOL) {
|
||||
$this->debug('Starting parallel fetch (HttpRequestPool)');
|
||||
try {
|
||||
while (count($urls) > 0) {
|
||||
$this->debug('Processing set of '.min($this->maxParallelRequests, count($urls)));
|
||||
$subset = array_splice($urls, 0, $this->maxParallelRequests);
|
||||
$pool = new HttpRequestPool();
|
||||
foreach ($subset as $orig => $url) {
|
||||
if (!$isRedirect) $orig = $url;
|
||||
unset($this->redirectQueue[$orig]);
|
||||
$this->debug("...$url");
|
||||
if (!$isRedirect && isset($this->requests[$url])) {
|
||||
$this->debug("......in memory");
|
||||
/*
|
||||
} elseif ($this->isCached($url)) {
|
||||
$this->debug("......is cached");
|
||||
if (!$this->minimiseMemoryUse) {
|
||||
$this->requests[$url] = $this->getCached($url);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
$this->debug("......adding to pool");
|
||||
$req_url = $this->rewriteUrls($url);
|
||||
$req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url;
|
||||
$req_url = $this->removeFragment($req_url);
|
||||
if (!empty($this->headerOnlyTypes) && !isset($this->requests[$orig]['wrongGuess']) && $this->possibleUnsupportedType($req_url)) {
|
||||
$_meth = HttpRequest::METH_HEAD;
|
||||
} else {
|
||||
$_meth = HttpRequest::METH_GET;
|
||||
unset($this->requests[$orig]['wrongGuess']);
|
||||
}
|
||||
$httpRequest = new HttpRequest($req_url, $_meth, $this->requestOptions);
|
||||
// send cookies, if we have any
|
||||
if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) {
|
||||
$this->debug("......sending cookies: $cookies");
|
||||
$httpRequest->addHeaders(array('Cookie' => $cookies));
|
||||
}
|
||||
//$httpRequest->addHeaders(array('User-Agent' => $this->userAgent));
|
||||
$httpRequest->addHeaders($this->getUserAgent($req_url, true));
|
||||
// add referer for picky sites
|
||||
$httpRequest->addheaders(array('Referer' => $this->referer));
|
||||
$this->requests[$orig] = array('headers'=>null, 'body'=>null, 'httpRequest'=>$httpRequest);
|
||||
$this->requests[$orig]['original_url'] = $orig;
|
||||
$pool->attach($httpRequest);
|
||||
}
|
||||
}
|
||||
// did we get anything into the pool?
|
||||
if (count($pool) > 0) {
|
||||
$this->debug('Sending request...');
|
||||
try {
|
||||
$pool->send();
|
||||
} catch (HttpRequestPoolException $e) {
|
||||
// do nothing
|
||||
}
|
||||
$this->debug('Received responses');
|
||||
foreach($subset as $orig => $url) {
|
||||
if (!$isRedirect) $orig = $url;
|
||||
$request = $this->requests[$orig]['httpRequest'];
|
||||
//$this->requests[$orig]['headers'] = $this->headersToString($request->getResponseHeader());
|
||||
// getResponseHeader() doesn't return status line, so, for consistency...
|
||||
$this->requests[$orig]['headers'] = substr($request->getRawResponseMessage(), 0, $request->getResponseInfo('header_size'));
|
||||
// check content type
|
||||
// TODO: use getResponseHeader('content-type') or getResponseInfo()
|
||||
if ($this->headerOnlyType($this->requests[$orig]['headers'])) {
|
||||
$this->requests[$orig]['body'] = '';
|
||||
$_header_only_type = true;
|
||||
$this->debug('Header only type returned');
|
||||
} else {
|
||||
$this->requests[$orig]['body'] = $request->getResponseBody();
|
||||
$_header_only_type = false;
|
||||
}
|
||||
$this->requests[$orig]['effective_url'] = $request->getResponseInfo('effective_url');
|
||||
$this->requests[$orig]['status_code'] = $status_code = $request->getResponseCode();
|
||||
// is redirect?
|
||||
if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && $request->getResponseHeader('location')) {
|
||||
$redirectURL = $request->getResponseHeader('location');
|
||||
if (!preg_match('!^https?://!i', $redirectURL)) {
|
||||
$redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url);
|
||||
}
|
||||
if ($this->validateURL($redirectURL)) {
|
||||
$this->debug('Redirect detected. Valid URL: '.$redirectURL);
|
||||
// store any cookies
|
||||
$cookies = $request->getResponseHeader('set-cookie');
|
||||
if ($cookies && !is_array($cookies)) $cookies = array($cookies);
|
||||
if ($cookies) $this->cookieJar->storeCookies($url, $cookies);
|
||||
$this->redirectQueue[$orig] = $redirectURL;
|
||||
} else {
|
||||
$this->debug('Redirect detected. Invalid URL: '.$redirectURL);
|
||||
}
|
||||
} elseif (!$_header_only_type && $request->getMethod() === HttpRequest::METH_HEAD) {
|
||||
// the response content-type did not match our 'header only' types,
|
||||
// but we'd issues a HEAD request because we assumed it would. So
|
||||
// let's queue a proper GET request for this item...
|
||||
$this->debug('Wrong guess at content-type, queing GET request');
|
||||
$this->requests[$orig]['wrongGuess'] = true;
|
||||
$this->redirectQueue[$orig] = $this->requests[$orig]['effective_url'];
|
||||
}
|
||||
//die($url.' -multi- '.$request->getResponseInfo('effective_url'));
|
||||
$pool->detach($request);
|
||||
unset($this->requests[$orig]['httpRequest'], $request);
|
||||
/*
|
||||
if ($this->minimiseMemoryUse) {
|
||||
if ($this->cache($url)) {
|
||||
unset($this->requests[$url]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (HttpException $e) {
|
||||
$this->debug($e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// parallel (curl_multi_*)
|
||||
elseif ($this->method == self::METHOD_CURL_MULTI) {
|
||||
$this->debug('Starting parallel fetch (curl_multi_*)');
|
||||
while (count($urls) > 0) {
|
||||
$this->debug('Processing set of '.min($this->maxParallelRequests, count($urls)));
|
||||
$subset = array_splice($urls, 0, $this->maxParallelRequests);
|
||||
$pool = new RollingCurl(array($this, 'handleCurlResponse'));
|
||||
$pool->window_size = count($subset);
|
||||
|
||||
foreach ($subset as $orig => $url) {
|
||||
if (!$isRedirect) $orig = $url;
|
||||
unset($this->redirectQueue[$orig]);
|
||||
$this->debug("...$url");
|
||||
if (!$isRedirect && isset($this->requests[$url])) {
|
||||
$this->debug("......in memory");
|
||||
/*
|
||||
} elseif ($this->isCached($url)) {
|
||||
$this->debug("......is cached");
|
||||
if (!$this->minimiseMemoryUse) {
|
||||
$this->requests[$url] = $this->getCached($url);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
$this->debug("......adding to pool");
|
||||
$req_url = $this->rewriteUrls($url);
|
||||
$req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url;
|
||||
$req_url = $this->removeFragment($req_url);
|
||||
if (!empty($this->headerOnlyTypes) && !isset($this->requests[$orig]['wrongGuess']) && $this->possibleUnsupportedType($req_url)) {
|
||||
$_meth = 'HEAD';
|
||||
} else {
|
||||
$_meth = 'GET';
|
||||
unset($this->requests[$orig]['wrongGuess']);
|
||||
}
|
||||
$headers = array();
|
||||
//$headers[] = 'User-Agent: '.$this->userAgent;
|
||||
$headers[] = $this->getUserAgent($req_url);
|
||||
// add referer for picky sites
|
||||
$headers[] = 'Referer: '.$this->referer;
|
||||
// send cookies, if we have any
|
||||
if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) {
|
||||
$this->debug("......sending cookies: $cookies");
|
||||
$headers[] = 'Cookie: '.$cookies;
|
||||
}
|
||||
$httpRequest = new RollingCurlRequest($req_url, $_meth, null, $headers, array(
|
||||
CURLOPT_CONNECTTIMEOUT => $this->requestOptions['timeout'],
|
||||
CURLOPT_TIMEOUT => $this->requestOptions['timeout']
|
||||
));
|
||||
$httpRequest->set_original_url($orig);
|
||||
$this->requests[$orig] = array('headers'=>null, 'body'=>null, 'httpRequest'=>$httpRequest);
|
||||
$this->requests[$orig]['original_url'] = $orig; // TODO: is this needed anymore?
|
||||
$pool->add($httpRequest);
|
||||
}
|
||||
}
|
||||
// did we get anything into the pool?
|
||||
if (count($pool) > 0) {
|
||||
$this->debug('Sending request...');
|
||||
$pool->execute(); // this will call handleCurlResponse() and populate $this->requests[$orig]
|
||||
$this->debug('Received responses');
|
||||
foreach($subset as $orig => $url) {
|
||||
if (!$isRedirect) $orig = $url;
|
||||
// $this->requests[$orig]['headers']
|
||||
// $this->requests[$orig]['body']
|
||||
// $this->requests[$orig]['effective_url']
|
||||
// check content type
|
||||
if ($this->headerOnlyType($this->requests[$orig]['headers'])) {
|
||||
$this->requests[$orig]['body'] = '';
|
||||
$_header_only_type = true;
|
||||
$this->debug('Header only type returned');
|
||||
} else {
|
||||
$_header_only_type = false;
|
||||
}
|
||||
$status_code = $this->requests[$orig]['status_code'];
|
||||
if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && isset($this->requests[$orig]['location'])) {
|
||||
$redirectURL = $this->requests[$orig]['location'];
|
||||
if (!preg_match('!^https?://!i', $redirectURL)) {
|
||||
$redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url);
|
||||
}
|
||||
if ($this->validateURL($redirectURL)) {
|
||||
$this->debug('Redirect detected. Valid URL: '.$redirectURL);
|
||||
// store any cookies
|
||||
$cookies = $this->cookieJar->extractCookies($this->requests[$orig]['headers']);
|
||||
if (!empty($cookies)) $this->cookieJar->storeCookies($url, $cookies);
|
||||
$this->redirectQueue[$orig] = $redirectURL;
|
||||
} else {
|
||||
$this->debug('Redirect detected. Invalid URL: '.$redirectURL);
|
||||
}
|
||||
} elseif (!$_header_only_type && $this->requests[$orig]['method'] == 'HEAD') {
|
||||
// the response content-type did not match our 'header only' types,
|
||||
// but we'd issues a HEAD request because we assumed it would. So
|
||||
// let's queue a proper GET request for this item...
|
||||
$this->debug('Wrong guess at content-type, queing GET request');
|
||||
$this->requests[$orig]['wrongGuess'] = true;
|
||||
$this->redirectQueue[$orig] = $this->requests[$orig]['effective_url'];
|
||||
}
|
||||
// die($url.' -multi- '.$request->getResponseInfo('effective_url'));
|
||||
unset($this->requests[$orig]['httpRequest'], $this->requests[$orig]['method']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// sequential (file_get_contents)
|
||||
else {
|
||||
$this->debug('Starting sequential fetch (file_get_contents)');
|
||||
$this->debug('Processing set of '.count($urls));
|
||||
foreach ($urls as $orig => $url) {
|
||||
if (!$isRedirect) $orig = $url;
|
||||
unset($this->redirectQueue[$orig]);
|
||||
$this->debug("...$url");
|
||||
if (!$isRedirect && isset($this->requests[$url])) {
|
||||
$this->debug("......in memory");
|
||||
/*
|
||||
} elseif ($this->isCached($url)) {
|
||||
$this->debug("......is cached");
|
||||
if (!$this->minimiseMemoryUse) {
|
||||
$this->requests[$url] = $this->getCached($url);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
$this->debug("Sending request for $url");
|
||||
$this->requests[$orig]['original_url'] = $orig;
|
||||
$req_url = $this->rewriteUrls($url);
|
||||
$req_url = ($this->rewriteHashbangFragment) ? $this->rewriteHashbangFragment($req_url) : $req_url;
|
||||
$req_url = $this->removeFragment($req_url);
|
||||
// send cookies, if we have any
|
||||
$httpContext = $this->httpContext;
|
||||
$httpContext['http']['header'] .= $this->getUserAgent($req_url)."\r\n";
|
||||
// add referer for picky sites
|
||||
$httpContext['http']['header'] .= 'Referer: '.$this->referer."\r\n";
|
||||
if ($cookies = $this->cookieJar->getMatchingCookies($req_url)) {
|
||||
$this->debug("......sending cookies: $cookies");
|
||||
$httpContext['http']['header'] .= 'Cookie: '.$cookies."\r\n";
|
||||
}
|
||||
if (false !== ($html = @file_get_contents($req_url, false, stream_context_create($httpContext)))) {
|
||||
$this->debug('Received response');
|
||||
// get status code
|
||||
if (!isset($http_response_header[0]) || !preg_match('!^HTTP/\d+\.\d+\s+(\d+)!', trim($http_response_header[0]), $match)) {
|
||||
$this->debug('Error: no status code found');
|
||||
// TODO: handle error - no status code
|
||||
} else {
|
||||
$this->requests[$orig]['headers'] = $this->headersToString($http_response_header, false);
|
||||
// check content type
|
||||
if ($this->headerOnlyType($this->requests[$orig]['headers'])) {
|
||||
$this->requests[$orig]['body'] = '';
|
||||
} else {
|
||||
$this->requests[$orig]['body'] = $html;
|
||||
}
|
||||
$this->requests[$orig]['effective_url'] = $req_url;
|
||||
$this->requests[$orig]['status_code'] = $status_code = (int)$match[1];
|
||||
unset($match);
|
||||
// handle redirect
|
||||
if (preg_match('/^Location:(.*?)$/m', $this->requests[$orig]['headers'], $match)) {
|
||||
$this->requests[$orig]['location'] = trim($match[1]);
|
||||
}
|
||||
if ((in_array($status_code, array(300, 301, 302, 303, 307)) || $status_code > 307 && $status_code < 400) && isset($this->requests[$orig]['location'])) {
|
||||
$redirectURL = $this->requests[$orig]['location'];
|
||||
if (!preg_match('!^https?://!i', $redirectURL)) {
|
||||
$redirectURL = SimplePie_Misc::absolutize_url($redirectURL, $url);
|
||||
}
|
||||
if ($this->validateURL($redirectURL)) {
|
||||
$this->debug('Redirect detected. Valid URL: '.$redirectURL);
|
||||
// store any cookies
|
||||
$cookies = $this->cookieJar->extractCookies($this->requests[$orig]['headers']);
|
||||
if (!empty($cookies)) $this->cookieJar->storeCookies($url, $cookies);
|
||||
$this->redirectQueue[$orig] = $redirectURL;
|
||||
} else {
|
||||
$this->debug('Redirect detected. Invalid URL: '.$redirectURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->debug('Error retrieving URL');
|
||||
//print_r($req_url);
|
||||
//print_r($http_response_header);
|
||||
//print_r($html);
|
||||
|
||||
// TODO: handle error - failed to retrieve URL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleCurlResponse($response, $info, $request) {
|
||||
$orig = $request->url_original;
|
||||
$this->requests[$orig]['headers'] = substr($response, 0, $info['header_size']);
|
||||
$this->requests[$orig]['body'] = substr($response, $info['header_size']);
|
||||
$this->requests[$orig]['method'] = $request->method;
|
||||
$this->requests[$orig]['effective_url'] = $info['url'];
|
||||
$this->requests[$orig]['status_code'] = (int)$info['http_code'];
|
||||
if (preg_match('/^Location:(.*?)$/m', $this->requests[$orig]['headers'], $match)) {
|
||||
$this->requests[$orig]['location'] = trim($match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function headersToString(array $headers, $associative=true) {
|
||||
if (!$associative) {
|
||||
return implode("\n", $headers);
|
||||
} else {
|
||||
$str = '';
|
||||
foreach ($headers as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
foreach ($val as $v) $str .= "$key: $v\n";
|
||||
} else {
|
||||
$str .= "$key: $val\n";
|
||||
}
|
||||
}
|
||||
return rtrim($str);
|
||||
}
|
||||
}
|
||||
|
||||
public function get($url, $remove=false, $gzdecode=true) {
|
||||
$url = "$url";
|
||||
if (isset($this->requests[$url]) && isset($this->requests[$url]['body'])) {
|
||||
$this->debug("URL already fetched - in memory ($url, effective: {$this->requests[$url]['effective_url']})");
|
||||
$response = $this->requests[$url];
|
||||
/*
|
||||
} elseif ($this->isCached($url)) {
|
||||
$this->debug("URL already fetched - in disk cache ($url)");
|
||||
$response = $this->getCached($url);
|
||||
$this->requests[$url] = $response;
|
||||
*/
|
||||
} else {
|
||||
$this->debug("Fetching URL ($url)");
|
||||
$this->fetchAll(array($url));
|
||||
if (isset($this->requests[$url]) && isset($this->requests[$url]['body'])) {
|
||||
$response = $this->requests[$url];
|
||||
} else {
|
||||
$this->debug("Request failed");
|
||||
$response = false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if ($this->minimiseMemoryUse && $response) {
|
||||
$this->cache($url);
|
||||
unset($this->requests[$url]);
|
||||
}
|
||||
*/
|
||||
if ($remove && $response) unset($this->requests[$url]);
|
||||
if ($gzdecode && stripos($response['headers'], 'Content-Encoding: gzip')) {
|
||||
if ($html = gzdecode($response['body'])) {
|
||||
$response['body'] = $html;
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function parallelSupport() {
|
||||
return class_exists('HttpRequestPool') || function_exists('curl_multi_init');
|
||||
}
|
||||
|
||||
private function headerOnlyType($headers) {
|
||||
if (preg_match('!^Content-Type:\s*(([a-z-]+)/([^;\r\n ]+))!im', $headers, $match)) {
|
||||
// look for full mime type (e.g. image/jpeg) or just type (e.g. image)
|
||||
$match[1] = strtolower(trim($match[1]));
|
||||
$match[2] = strtolower(trim($match[2]));
|
||||
foreach (array($match[1], $match[2]) as $mime) {
|
||||
if (in_array($mime, $this->headerOnlyTypes)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function possibleUnsupportedType($url) {
|
||||
$path = @parse_url($url, PHP_URL_PATH);
|
||||
if ($path && strpos($path, '.') !== false) {
|
||||
$ext = strtolower(trim(pathinfo($path, PATHINFO_EXTENSION)));
|
||||
return in_array($ext, $this->headerOnlyClues);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// gzdecode from http://www.php.net/manual/en/function.gzdecode.php#82930
|
||||
if (!function_exists('gzdecode')) {
|
||||
function gzdecode($data,&$filename='',&$error='',$maxlength=null)
|
||||
{
|
||||
$len = strlen($data);
|
||||
if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) {
|
||||
$error = "Not in GZIP format.";
|
||||
return null; // Not GZIP format (See RFC 1952)
|
||||
}
|
||||
$method = ord(substr($data,2,1)); // Compression method
|
||||
$flags = ord(substr($data,3,1)); // Flags
|
||||
if ($flags & 31 != $flags) {
|
||||
$error = "Reserved bits not allowed.";
|
||||
return null;
|
||||
}
|
||||
// NOTE: $mtime may be negative (PHP integer limitations)
|
||||
$mtime = unpack("V", substr($data,4,4));
|
||||
$mtime = $mtime[1];
|
||||
$xfl = substr($data,8,1);
|
||||
$os = substr($data,8,1);
|
||||
$headerlen = 10;
|
||||
$extralen = 0;
|
||||
$extra = "";
|
||||
if ($flags & 4) {
|
||||
// 2-byte length prefixed EXTRA data in header
|
||||
if ($len - $headerlen - 2 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$extralen = unpack("v",substr($data,8,2));
|
||||
$extralen = $extralen[1];
|
||||
if ($len - $headerlen - 2 - $extralen < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$extra = substr($data,10,$extralen);
|
||||
$headerlen += 2 + $extralen;
|
||||
}
|
||||
$filenamelen = 0;
|
||||
$filename = "";
|
||||
if ($flags & 8) {
|
||||
// C-style string
|
||||
if ($len - $headerlen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$filenamelen = strpos(substr($data,$headerlen),chr(0));
|
||||
if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$filename = substr($data,$headerlen,$filenamelen);
|
||||
$headerlen += $filenamelen + 1;
|
||||
}
|
||||
$commentlen = 0;
|
||||
$comment = "";
|
||||
if ($flags & 16) {
|
||||
// C-style string COMMENT data in header
|
||||
if ($len - $headerlen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$commentlen = strpos(substr($data,$headerlen),chr(0));
|
||||
if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {
|
||||
return false; // Invalid header format
|
||||
}
|
||||
$comment = substr($data,$headerlen,$commentlen);
|
||||
$headerlen += $commentlen + 1;
|
||||
}
|
||||
$headercrc = "";
|
||||
if ($flags & 2) {
|
||||
// 2-bytes (lowest order) of CRC32 on header present
|
||||
if ($len - $headerlen - 2 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$calccrc = crc32(substr($data,0,$headerlen)) & 0xffff;
|
||||
$headercrc = unpack("v", substr($data,$headerlen,2));
|
||||
$headercrc = $headercrc[1];
|
||||
if ($headercrc != $calccrc) {
|
||||
$error = "Header checksum failed.";
|
||||
return false; // Bad header CRC
|
||||
}
|
||||
$headerlen += 2;
|
||||
}
|
||||
// GZIP FOOTER
|
||||
$datacrc = unpack("V",substr($data,-8,4));
|
||||
$datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF);
|
||||
$isize = unpack("V",substr($data,-4));
|
||||
$isize = $isize[1];
|
||||
// decompression:
|
||||
$bodylen = $len-$headerlen-8;
|
||||
if ($bodylen < 1) {
|
||||
// IMPLEMENTATION BUG!
|
||||
return null;
|
||||
}
|
||||
$body = substr($data,$headerlen,$bodylen);
|
||||
$data = "";
|
||||
if ($bodylen > 0) {
|
||||
switch ($method) {
|
||||
case 8:
|
||||
// Currently the only supported compression method:
|
||||
$data = gzinflate($body,$maxlength);
|
||||
break;
|
||||
default:
|
||||
$error = "Unknown compression method.";
|
||||
return false;
|
||||
}
|
||||
} // zero-byte body content is allowed
|
||||
// Verifiy CRC32
|
||||
$crc = sprintf("%u",crc32($data));
|
||||
$crcOK = $crc == $datacrc;
|
||||
$lenOK = $isize == strlen($data);
|
||||
if (!$lenOK || !$crcOK) {
|
||||
$error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.');
|
||||
return false;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
?>
|
||||
402
inc/3rdparty/humble-http-agent/RollingCurl.php
vendored
402
inc/3rdparty/humble-http-agent/RollingCurl.php
vendored
@ -1,402 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Authored by Josh Fraser (www.joshfraser.com)
|
||||
Released under Apache License 2.0
|
||||
|
||||
Maintained by Alexander Makarov, http://rmcreative.ru/
|
||||
|
||||
Modified by Keyvan Minoukadeh for the Five Filters project: http://fivefilters.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represent a single curl request
|
||||
*/
|
||||
class RollingCurlRequest {
|
||||
public $url = false;
|
||||
public $url_original = false; // used for tracking redirects
|
||||
public $method = 'GET';
|
||||
public $post_data = null;
|
||||
public $headers = null;
|
||||
public $options = null;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param $post_data
|
||||
* @param $headers
|
||||
* @param $options
|
||||
* @return void
|
||||
*/
|
||||
function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
|
||||
$this->url = $url;
|
||||
$this->url_original = $url;
|
||||
$this->method = $method;
|
||||
$this->post_data = $post_data;
|
||||
$this->headers = $headers;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return void
|
||||
*/
|
||||
public function set_original_url($url) {
|
||||
$this->url_original = $url;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct() {
|
||||
unset($this->url, $this->url_original, $this->method, $this->post_data, $this->headers, $this->options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RollingCurl custom exception
|
||||
*/
|
||||
class RollingCurlException extends Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that holds a rolling queue of curl requests.
|
||||
*
|
||||
* @throws RollingCurlException
|
||||
*/
|
||||
class RollingCurl implements Countable {
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
* Window size is the max number of simultaneous connections allowed.
|
||||
*
|
||||
* REMEMBER TO RESPECT THE SERVERS:
|
||||
* Sending too many requests at one time can easily be perceived
|
||||
* as a DOS attack. Increase this window_size if you are making requests
|
||||
* to multiple servers or have permission from the receving server admins.
|
||||
*/
|
||||
private $window_size = 5;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*
|
||||
* Timeout is the timeout used for curl_multi_select.
|
||||
*/
|
||||
private $timeout = 10;
|
||||
|
||||
/**
|
||||
* @var string|array
|
||||
*
|
||||
* Callback function to be applied to each result.
|
||||
*/
|
||||
private $callback;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* Set your base options that you want to be used with EVERY request.
|
||||
*/
|
||||
protected $options = array(
|
||||
CURLOPT_SSL_VERIFYPEER => 0,
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_CONNECTTIMEOUT => 30,
|
||||
CURLOPT_TIMEOUT => 30
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $headers = array();
|
||||
|
||||
/**
|
||||
* @var Request[]
|
||||
*
|
||||
* The request queue
|
||||
*/
|
||||
private $requests = array();
|
||||
|
||||
/**
|
||||
* @var RequestMap[]
|
||||
*
|
||||
* Maps handles to request indexes
|
||||
*/
|
||||
private $requestMap = array();
|
||||
|
||||
/**
|
||||
* @param $callback
|
||||
* Callback function to be applied to each result.
|
||||
*
|
||||
* Can be specified as 'my_callback_function'
|
||||
* or array($object, 'my_callback_method').
|
||||
*
|
||||
* Function should take three parameters: $response, $info, $request.
|
||||
* $response is response body, $info is additional curl info.
|
||||
* $request is the original request
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct($callback = null) {
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name) {
|
||||
return (isset($this->{$name})) ? $this->{$name} : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
// append the base options & headers
|
||||
if ($name == "options" || $name == "headers") {
|
||||
$this->{$name} = $value + $this->{$name};
|
||||
} else {
|
||||
$this->{$name} = $value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of requests added (Countable interface)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count() {
|
||||
return count($this->requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a request to the request queue
|
||||
*
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
public function add($request) {
|
||||
$this->requests[] = $request;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new Request and add it to the request queue
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param $post_data
|
||||
* @param $headers
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
|
||||
$this->requests[] = new RollingCurlRequest($url, $method, $post_data, $headers, $options);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform GET request
|
||||
*
|
||||
* @param string $url
|
||||
* @param $headers
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
public function get($url, $headers = null, $options = null) {
|
||||
return $this->request($url, "GET", null, $headers, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform POST request
|
||||
*
|
||||
* @param string $url
|
||||
* @param $post_data
|
||||
* @param $headers
|
||||
* @param $options
|
||||
* @return bool
|
||||
*/
|
||||
public function post($url, $post_data = null, $headers = null, $options = null) {
|
||||
return $this->request($url, "POST", $post_data, $headers, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute processing
|
||||
*
|
||||
* @param int $window_size Max number of simultaneous connections
|
||||
* @return string|bool
|
||||
*/
|
||||
public function execute($window_size = null) {
|
||||
// rolling curl window must always be greater than 1
|
||||
if (sizeof($this->requests) == 1) {
|
||||
return $this->single_curl();
|
||||
} else {
|
||||
// start the rolling curl. window_size is the max number of simultaneous connections
|
||||
return $this->rolling_curl($window_size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a single curl request
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function single_curl() {
|
||||
$ch = curl_init();
|
||||
$request = array_shift($this->requests);
|
||||
$options = $this->get_options($request);
|
||||
curl_setopt_array($ch, $options);
|
||||
$output = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
|
||||
// it's not neccesary to set a callback for one-off requests
|
||||
if ($this->callback) {
|
||||
$callback = $this->callback;
|
||||
if (is_callable($this->callback)) {
|
||||
call_user_func($callback, $output, $info, $request);
|
||||
}
|
||||
}
|
||||
else
|
||||
return $output;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs multiple curl requests
|
||||
*
|
||||
* @access private
|
||||
* @throws RollingCurlException
|
||||
* @param int $window_size Max number of simultaneous connections
|
||||
* @return bool
|
||||
*/
|
||||
private function rolling_curl($window_size = null) {
|
||||
if ($window_size)
|
||||
$this->window_size = $window_size;
|
||||
|
||||
// make sure the rolling window isn't greater than the # of urls
|
||||
if (sizeof($this->requests) < $this->window_size)
|
||||
$this->window_size = sizeof($this->requests);
|
||||
|
||||
if ($this->window_size < 2) {
|
||||
throw new RollingCurlException("Window size must be greater than 1");
|
||||
}
|
||||
|
||||
$master = curl_multi_init();
|
||||
|
||||
// start the first batch of requests
|
||||
for ($i = 0; $i < $this->window_size; $i++) {
|
||||
$ch = curl_init();
|
||||
|
||||
$options = $this->get_options($this->requests[$i]);
|
||||
|
||||
curl_setopt_array($ch, $options);
|
||||
curl_multi_add_handle($master, $ch);
|
||||
|
||||
// Add to our request Maps
|
||||
$key = (string) $ch;
|
||||
$this->requestMap[$key] = $i;
|
||||
}
|
||||
|
||||
do {
|
||||
while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM) ;
|
||||
if ($execrun != CURLM_OK)
|
||||
break;
|
||||
// a request was just completed -- find out which one
|
||||
while ($done = curl_multi_info_read($master)) {
|
||||
|
||||
// get the info and content returned on the request
|
||||
$info = curl_getinfo($done['handle']);
|
||||
$output = curl_multi_getcontent($done['handle']);
|
||||
|
||||
// send the return values to the callback function.
|
||||
$callback = $this->callback;
|
||||
if (is_callable($callback)) {
|
||||
$key = (string) $done['handle'];
|
||||
$request = $this->requests[$this->requestMap[$key]];
|
||||
unset($this->requestMap[$key]);
|
||||
call_user_func($callback, $output, $info, $request);
|
||||
}
|
||||
|
||||
// start a new request (it's important to do this before removing the old one)
|
||||
if ($i < sizeof($this->requests) && isset($this->requests[$i]) && $i < count($this->requests)) {
|
||||
$ch = curl_init();
|
||||
$options = $this->get_options($this->requests[$i]);
|
||||
curl_setopt_array($ch, $options);
|
||||
curl_multi_add_handle($master, $ch);
|
||||
|
||||
// Add to our request Maps
|
||||
$key = (string) $ch;
|
||||
$this->requestMap[$key] = $i;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// remove the curl handle that just completed
|
||||
curl_multi_remove_handle($master, $done['handle']);
|
||||
|
||||
}
|
||||
|
||||
// Block for data in / output; error handling is done by curl_multi_exec
|
||||
//if ($running) curl_multi_select($master, $this->timeout);
|
||||
// removing timeout as it causes problems on Windows with PHP 5.3.5 and Curl 7.20.0
|
||||
if ($running) curl_multi_select($master);
|
||||
|
||||
} while ($running);
|
||||
curl_multi_close($master);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to set up a new request by setting the appropriate options
|
||||
*
|
||||
* @access private
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
private function get_options($request) {
|
||||
// options for this entire curl object
|
||||
$options = $this->__get('options');
|
||||
// We're managing reirects in PHP - allows us to intervene and rewrite/block URLs
|
||||
// before the next request goes out.
|
||||
$options[CURLOPT_FOLLOWLOCATION] = 0;
|
||||
$options[CURLOPT_MAXREDIRS] = 0;
|
||||
//if (ini_get('safe_mode') == 'Off' || !ini_get('safe_mode')) {
|
||||
// $options[CURLOPT_FOLLOWLOCATION] = 1;
|
||||
// $options[CURLOPT_MAXREDIRS] = 5;
|
||||
//}
|
||||
$headers = $this->__get('headers');
|
||||
// append custom headers for this specific request
|
||||
if ($request->headers) {
|
||||
$headers = $headers + $request->headers;
|
||||
}
|
||||
|
||||
// append custom options for this specific request
|
||||
if ($request->options) {
|
||||
$options = $request->options + $options;
|
||||
}
|
||||
|
||||
// set the request URL
|
||||
$options[CURLOPT_URL] = $request->url;
|
||||
|
||||
if ($headers) {
|
||||
$options[CURLOPT_HTTPHEADER] = $headers;
|
||||
}
|
||||
// return response headers
|
||||
$options[CURLOPT_HEADER] = 1;
|
||||
|
||||
// send HEAD request?
|
||||
if ($request->method == 'HEAD') {
|
||||
$options[CURLOPT_NOBODY] = 1;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct() {
|
||||
unset($this->window_size, $this->callback, $this->options, $this->headers, $this->requests);
|
||||
}
|
||||
}
|
||||
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Humble HTTP Agent extension for SimplePie_File
|
||||
*
|
||||
* This class is designed to extend and override SimplePie_File
|
||||
* in order to prevent duplicate HTTP requests being sent out.
|
||||
* The idea is to initialise an instance of Humble HTTP Agent
|
||||
* and attach it, to a static class variable, of this class.
|
||||
* SimplePie will then automatically initialise this class
|
||||
*
|
||||
* @date 2011-02-28
|
||||
*/
|
||||
|
||||
class SimplePie_HumbleHttpAgent extends SimplePie_File
|
||||
{
|
||||
protected static $agent;
|
||||
var $url;
|
||||
var $useragent;
|
||||
var $success = true;
|
||||
var $headers = array();
|
||||
var $body;
|
||||
var $status_code;
|
||||
var $redirects = 0;
|
||||
var $error;
|
||||
var $method = SIMPLEPIE_FILE_SOURCE_NONE;
|
||||
|
||||
public static function set_agent(HumbleHttpAgent $agent) {
|
||||
self::$agent = $agent;
|
||||
}
|
||||
|
||||
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
||||
if (class_exists('idna_convert'))
|
||||
{
|
||||
$idn = new idna_convert();
|
||||
$parsed = SimplePie_Misc::parse_url($url);
|
||||
$url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
|
||||
}
|
||||
$this->url = $url;
|
||||
$this->useragent = $useragent;
|
||||
if (preg_match('/^http(s)?:\/\//i', $url))
|
||||
{
|
||||
if (!is_array($headers))
|
||||
{
|
||||
$headers = array();
|
||||
}
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
|
||||
$headers2 = array();
|
||||
foreach ($headers as $key => $value) {
|
||||
$headers2[] = "$key: $value";
|
||||
}
|
||||
//TODO: allow for HTTP headers
|
||||
// curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
|
||||
|
||||
$response = self::$agent->get($url);
|
||||
|
||||
if ($response === false || !isset($response['status_code'])) {
|
||||
$this->error = 'failed to fetch URL';
|
||||
$this->success = false;
|
||||
} else {
|
||||
// The extra lines at the end are there to satisfy SimplePie's HTTP parser.
|
||||
// The class expects a full HTTP message, whereas we're giving it only
|
||||
// headers - the new lines indicate the start of the body.
|
||||
$parser = new SimplePie_HTTP_Parser($response['headers']."\r\n\r\n");
|
||||
if ($parser->parse()) {
|
||||
$this->headers = $parser->headers;
|
||||
//$this->body = $parser->body;
|
||||
$this->body = $response['body'];
|
||||
$this->status_code = $parser->status_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error = 'invalid URL';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
202
inc/3rdparty/paginator.php
vendored
202
inc/3rdparty/paginator.php
vendored
@ -1,202 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP Pagination Class
|
||||
*
|
||||
* @author David Carr - dave@daveismyname.com - http://www.daveismyname.com
|
||||
* @version 1.0
|
||||
* @date October 20, 2013
|
||||
*/
|
||||
class Paginator{
|
||||
|
||||
/**
|
||||
* set the number of items per page.
|
||||
*
|
||||
* @var numeric
|
||||
*/
|
||||
private $_perPage;
|
||||
|
||||
/**
|
||||
* set get parameter for fetching the page number
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_instance;
|
||||
|
||||
/**
|
||||
* sets the page number.
|
||||
*
|
||||
* @var numeric
|
||||
*/
|
||||
private $_page;
|
||||
|
||||
/**
|
||||
* set the limit for the data source
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_limit;
|
||||
|
||||
/**
|
||||
* set the total number of records/items.
|
||||
*
|
||||
* @var numeric
|
||||
*/
|
||||
private $_totalRows = 0;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* pass values when class is istantiated
|
||||
*
|
||||
* @param numeric $_perPage sets the number of iteems per page
|
||||
* @param numeric $_instance sets the instance for the GET parameter
|
||||
*/
|
||||
public function __construct($perPage,$instance){
|
||||
$this->_instance = $instance;
|
||||
$this->_perPage = $perPage;
|
||||
$this->set_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_start
|
||||
*
|
||||
* creates the starting point for limiting the dataset
|
||||
* @return numeric
|
||||
*/
|
||||
private function get_start(){
|
||||
return ($this->_page * $this->_perPage) - $this->_perPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_instance
|
||||
*
|
||||
* sets the instance parameter, if numeric value is 0 then set to 1
|
||||
*
|
||||
* @var numeric
|
||||
*/
|
||||
private function set_instance(){
|
||||
$this->_page = (int) (!isset($_GET[$this->_instance]) ? 1 : $_GET[$this->_instance]);
|
||||
$this->_page = ($this->_page == 0 ? 1 : $this->_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_total
|
||||
*
|
||||
* collect a numberic value and assigns it to the totalRows
|
||||
*
|
||||
* @var numeric
|
||||
*/
|
||||
public function set_total($_totalRows){
|
||||
$this->_totalRows = $_totalRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_limit
|
||||
*
|
||||
* returns the limit for the data source, calling the get_start method and passing in the number of items perp page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_limit(){
|
||||
if (STORAGE == 'postgres') {
|
||||
return "LIMIT ".$this->_perPage." OFFSET ".$this->get_start();
|
||||
} else {
|
||||
return "LIMIT ".$this->get_start().",".$this->_perPage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* page_links
|
||||
*
|
||||
* create the html links for navigating through the dataset
|
||||
*
|
||||
* @var sting $path optionally set the path for the link
|
||||
* @var sting $ext optionally pass in extra parameters to the GET
|
||||
* @return string returns the html menu
|
||||
*/
|
||||
public function page_links($path='?',$ext=null)
|
||||
{
|
||||
$adjacents = "2";
|
||||
$prev = $this->_page - 1;
|
||||
$next = $this->_page + 1;
|
||||
$lastpage = ceil($this->_totalRows/$this->_perPage);
|
||||
$lpm1 = $lastpage - 1;
|
||||
|
||||
$pagination = "";
|
||||
if($lastpage > 1)
|
||||
{
|
||||
$pagination .= "<div class='pagination'>";
|
||||
if ($this->_page > 1)
|
||||
$pagination.= "<a href='".$path."$this->_instance=$prev"."$ext'>« previous</a>";
|
||||
else
|
||||
$pagination.= "<span class='disabled'>« previous</span>";
|
||||
|
||||
if ($lastpage < 7 + ($adjacents * 2))
|
||||
{
|
||||
for ($counter = 1; $counter <= $lastpage; $counter++)
|
||||
{
|
||||
if ($counter == $this->_page)
|
||||
$pagination.= "<span class='current'>$counter</span>";
|
||||
else
|
||||
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
|
||||
}
|
||||
}
|
||||
elseif($lastpage > 5 + ($adjacents * 2))
|
||||
{
|
||||
if($this->_page < 1 + ($adjacents * 2))
|
||||
{
|
||||
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
|
||||
{
|
||||
if ($counter == $this->_page)
|
||||
$pagination.= "<span class='current'>$counter</span>";
|
||||
else
|
||||
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
|
||||
}
|
||||
$pagination.= "...";
|
||||
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
|
||||
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
|
||||
}
|
||||
elseif($lastpage - ($adjacents * 2) > $this->_page && $this->_page > ($adjacents * 2))
|
||||
{
|
||||
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
|
||||
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
|
||||
$pagination.= "...";
|
||||
for ($counter = $this->_page - $adjacents; $counter <= $this->_page + $adjacents; $counter++)
|
||||
{
|
||||
if ($counter == $this->_page)
|
||||
$pagination.= "<span class='current'>$counter</span>";
|
||||
else
|
||||
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
|
||||
}
|
||||
$pagination.= "..";
|
||||
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
|
||||
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
|
||||
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
|
||||
$pagination.= "..";
|
||||
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++)
|
||||
{
|
||||
if ($counter == $this->_page)
|
||||
$pagination.= "<span class='current'>$counter</span>";
|
||||
else
|
||||
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_page < $counter - 1)
|
||||
$pagination.= "<a href='".$path."$this->_instance=$next"."$ext'>next »</a>";
|
||||
else
|
||||
$pagination.= "<span class='disabled'>next »</span>";
|
||||
$pagination.= "</div>\n";
|
||||
}
|
||||
|
||||
|
||||
return $pagination;
|
||||
}
|
||||
}
|
||||
1722
inc/3rdparty/simple_html_dom.php
vendored
1722
inc/3rdparty/simple_html_dom.php
vendored
File diff suppressed because it is too large
Load Diff
26
inc/3rdparty/simplepie/LICENSE.txt
vendored
26
inc/3rdparty/simplepie/LICENSE.txt
vendored
@ -1,26 +0,0 @@
|
||||
Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
* Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
56
inc/3rdparty/simplepie/SimplePie.php
vendored
56
inc/3rdparty/simplepie/SimplePie.php
vendored
@ -1,56 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
/**
|
||||
* SimplePie class.
|
||||
*
|
||||
* Class for backward compatibility.
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie extends SimplePie_Core
|
||||
{
|
||||
|
||||
}
|
||||
103
inc/3rdparty/simplepie/SimplePie/Author.php
vendored
103
inc/3rdparty/simplepie/SimplePie/Author.php
vendored
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Author
|
||||
{
|
||||
var $name;
|
||||
var $link;
|
||||
var $email;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($name = null, $link = null, $email = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->link = $link;
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
if ($this->name !== null)
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
if ($this->link !== null)
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_email()
|
||||
{
|
||||
if ($this->email !== null)
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
109
inc/3rdparty/simplepie/SimplePie/Cache.php
vendored
109
inc/3rdparty/simplepie/SimplePie/Cache.php
vendored
@ -1,109 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Cache
|
||||
{
|
||||
/**
|
||||
* Cache handler classes
|
||||
*
|
||||
* These receive 3 parameters to their constructor, as documented in
|
||||
* {@see register()}
|
||||
* @var array
|
||||
*/
|
||||
protected static $handlers = array(
|
||||
'mysql' => 'SimplePie_Cache_MySQL',
|
||||
'memcache' => 'SimplePie_Cache_Memcache',
|
||||
);
|
||||
|
||||
/**
|
||||
* Don't call the constructor. Please.
|
||||
*/
|
||||
private function __construct() { }
|
||||
|
||||
/**
|
||||
* Create a new SimplePie_Cache object
|
||||
*/
|
||||
public static function create($location, $filename, $extension)
|
||||
{
|
||||
$type = explode(':', $location, 2);
|
||||
$type = $type[0];
|
||||
if (!empty(self::$handlers[$type]))
|
||||
{
|
||||
$class = self::$handlers[$type];
|
||||
return new $class($location, $filename, $extension);
|
||||
}
|
||||
|
||||
return new SimplePie_Cache_File($location, $filename, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler
|
||||
*
|
||||
* @param string $type DSN type to register for
|
||||
* @param string $class Name of handler class. Must implement SimplePie_Cache_Base
|
||||
*/
|
||||
public static function register($type, $class)
|
||||
{
|
||||
self::$handlers[$type] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a URL into an array
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_URL($url)
|
||||
{
|
||||
$params = parse_url($url);
|
||||
$params['extras'] = array();
|
||||
if (isset($params['query']))
|
||||
{
|
||||
parse_str($params['query'], $params['extras']);
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
102
inc/3rdparty/simplepie/SimplePie/Cache/Base.php
vendored
102
inc/3rdparty/simplepie/SimplePie/Cache/Base.php
vendored
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
interface SimplePie_Cache_Base
|
||||
{
|
||||
/**
|
||||
* Feed cache type
|
||||
*/
|
||||
const TYPE_FEED = 'spc';
|
||||
|
||||
/**
|
||||
* Image cache type
|
||||
*/
|
||||
const TYPE_IMAGE = 'spi';
|
||||
|
||||
/**
|
||||
* Create a new cache object
|
||||
*
|
||||
* @param string $location Location string (from SimplePie::$cache_location)
|
||||
* @param string $name Unique ID for the cache
|
||||
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
|
||||
*/
|
||||
public function __construct($location, $name, $type);
|
||||
|
||||
/**
|
||||
* Save data to the cache
|
||||
*
|
||||
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
|
||||
*/
|
||||
public function save($data);
|
||||
|
||||
/**
|
||||
* Retrieve the data saved to the cache
|
||||
*
|
||||
* @return array Data for SimplePie::$data
|
||||
*/
|
||||
public function load();
|
||||
|
||||
/**
|
||||
* Retrieve the last modified time for the cache
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function mtime();
|
||||
|
||||
/**
|
||||
* Set the last modified time to the current time
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function touch();
|
||||
|
||||
/**
|
||||
* Remove the cache
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function unlink();
|
||||
}
|
||||
124
inc/3rdparty/simplepie/SimplePie/Cache/DB.php
vendored
124
inc/3rdparty/simplepie/SimplePie/Cache/DB.php
vendored
@ -1,124 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
|
||||
{
|
||||
protected static function prepare_simplepie_object_for_cache(&$data)
|
||||
{
|
||||
$items = $data->get_items();
|
||||
$items_by_id = array();
|
||||
|
||||
if (!empty($items))
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$items_by_id[$item->get_id()] = $item;
|
||||
}
|
||||
|
||||
if (count($items_by_id) !== count($items))
|
||||
{
|
||||
$items_by_id = array();
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$items_by_id[$item->get_id(true)] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$channel = null;
|
||||
}
|
||||
|
||||
if ($channel !== null)
|
||||
{
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
|
||||
}
|
||||
}
|
||||
if (isset($data->data['items']))
|
||||
{
|
||||
unset($data->data['items']);
|
||||
}
|
||||
if (isset($data->data['ordered_items']))
|
||||
{
|
||||
unset($data->data['ordered_items']);
|
||||
}
|
||||
}
|
||||
return array(serialize($data->data), $items_by_id);
|
||||
}
|
||||
}
|
||||
112
inc/3rdparty/simplepie/SimplePie/Cache/File.php
vendored
112
inc/3rdparty/simplepie/SimplePie/Cache/File.php
vendored
@ -1,112 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Cache_File implements SimplePie_Cache_Base
|
||||
{
|
||||
protected $location;
|
||||
protected $filename;
|
||||
protected $extension;
|
||||
protected $name;
|
||||
|
||||
public function __construct($location, $filename, $extension)
|
||||
{
|
||||
$this->location = $location;
|
||||
$this->filename = $filename;
|
||||
$this->extension = $extension;
|
||||
$this->name = "$this->location/$this->filename.$this->extension";
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
|
||||
{
|
||||
if (is_a($data, 'SimplePie'))
|
||||
{
|
||||
$data = $data->data;
|
||||
}
|
||||
|
||||
$data = serialize($data);
|
||||
return (bool) file_put_contents($this->name, $data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function load()
|
||||
{
|
||||
if (file_exists($this->name) && is_readable($this->name))
|
||||
{
|
||||
return unserialize(file_get_contents($this->name));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function mtime()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return filemtime($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function touch()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return touch($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function unlink()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return unlink($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
118
inc/3rdparty/simplepie/SimplePie/Cache/Memcache.php
vendored
118
inc/3rdparty/simplepie/SimplePie/Cache/Memcache.php
vendored
@ -1,118 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
|
||||
{
|
||||
protected $cache;
|
||||
protected $options;
|
||||
protected $name;
|
||||
|
||||
public function __construct($url, $filename, $extension)
|
||||
{
|
||||
$this->options = array(
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 11211,
|
||||
'extras' => array(
|
||||
'timeout' => 3600, // one hour
|
||||
'prefix' => 'simplepie_',
|
||||
),
|
||||
);
|
||||
$this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($url));
|
||||
$this->name = $this->options['extras']['prefix'] . md5("$filename:$extension");
|
||||
|
||||
$this->cache = new Memcache();
|
||||
$this->cache->addServer($this->options['host'], (int) $this->options['port']);
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
if (is_a($data, 'SimplePie'))
|
||||
{
|
||||
$data = $data->data;
|
||||
}
|
||||
return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
|
||||
}
|
||||
|
||||
public function load()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
return unserialize($data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function mtime()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
// essentially ignore the mtime because Memcache expires on it's own
|
||||
return time();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function touch()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function unlink()
|
||||
{
|
||||
return $this->cache->delete($this->name);
|
||||
}
|
||||
}
|
||||
378
inc/3rdparty/simplepie/SimplePie/Cache/MySQL.php
vendored
378
inc/3rdparty/simplepie/SimplePie/Cache/MySQL.php
vendored
@ -1,378 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
|
||||
{
|
||||
protected $mysql;
|
||||
protected $options;
|
||||
protected $id;
|
||||
|
||||
public function __construct($url, $name, $extension)
|
||||
{
|
||||
$this->options = array(
|
||||
'user' => null,
|
||||
'pass' => null,
|
||||
'host' => '127.0.0.1',
|
||||
'port' => '3306',
|
||||
'path' => '',
|
||||
'extras' => array(
|
||||
'prefix' => '',
|
||||
),
|
||||
);
|
||||
$this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($url));
|
||||
|
||||
// Path is prefixed with a "/"
|
||||
$this->options['dbname'] = substr($this->options['path'], 1);
|
||||
|
||||
try
|
||||
{
|
||||
$this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
$this->mysql = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = $name . $extension;
|
||||
|
||||
if (!$query = $this->mysql->query('SHOW TABLES'))
|
||||
{
|
||||
$this->mysql = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$db = array();
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$db[] = $row;
|
||||
}
|
||||
|
||||
if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
|
||||
{
|
||||
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
|
||||
if ($query === false)
|
||||
{
|
||||
$this->mysql = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($this->options['extras']['prefix'] . 'items', $db))
|
||||
{
|
||||
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
|
||||
if ($query === false)
|
||||
{
|
||||
$this->mysql = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_a($data, 'SimplePie'))
|
||||
{
|
||||
$data = clone $data;
|
||||
|
||||
$prepared = self::prepare_simplepie_object_for_cache($data);
|
||||
|
||||
$query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
if ($query->fetchColumn() > 0)
|
||||
{
|
||||
$items = count($prepared[1]);
|
||||
if ($items)
|
||||
{
|
||||
$sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
|
||||
$query = $this->mysql->prepare($sql);
|
||||
$query->bindValue(':items', $items);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
|
||||
$query = $this->mysql->prepare($sql);
|
||||
}
|
||||
|
||||
$query->bindValue(':data', $prepared[0]);
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
$query->bindValue(':count', count($prepared[1]));
|
||||
$query->bindValue(':data', $prepared[0]);
|
||||
$query->bindValue(':time', time());
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$ids = array_keys($prepared[1]);
|
||||
if (!empty($ids))
|
||||
{
|
||||
foreach ($ids as $id)
|
||||
{
|
||||
$database_ids[] = $this->mysql->quote($id);
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
|
||||
if ($query->execute())
|
||||
{
|
||||
$existing_ids = array();
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$existing_ids[] = $row;
|
||||
}
|
||||
|
||||
$new_ids = array_diff($ids, $existing_ids);
|
||||
|
||||
foreach ($new_ids as $new_id)
|
||||
{
|
||||
if (!($date = $prepared[1][$new_id]->get_date('U')))
|
||||
{
|
||||
$date = time();
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
$query->bindValue(':id', $new_id);
|
||||
$query->bindValue(':data', serialize($prepared[1][$new_id]->data));
|
||||
$query->bindValue(':date', $date);
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
if ($query->rowCount() > 0)
|
||||
{
|
||||
$query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
|
||||
$query->bindValue(':data', serialize($data));
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($this->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
|
||||
$query->bindValue(':id', $this->id);
|
||||
$query->bindValue(':data', serialize($data));
|
||||
$query->bindValue(':time', time());
|
||||
if ($query->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function load()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && ($row = $query->fetch()))
|
||||
{
|
||||
$data = unserialize($row[1]);
|
||||
|
||||
if (isset($this->options['items'][0]))
|
||||
{
|
||||
$items = (int) $this->options['items'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$items = (int) $row[0];
|
||||
}
|
||||
|
||||
if ($items !== 0)
|
||||
{
|
||||
if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$feed = null;
|
||||
}
|
||||
|
||||
if ($feed !== null)
|
||||
{
|
||||
$sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
|
||||
if ($items > 0)
|
||||
{
|
||||
$sql .= ' LIMIT ' . $items;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare($sql);
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function mtime()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && ($time = $query->fetchColumn()))
|
||||
{
|
||||
return $time;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function touch()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && $query->rowCount() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function unlink()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
$query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
|
||||
$query2->bindValue(':id', $this->id);
|
||||
if ($query->execute() && $query2->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
131
inc/3rdparty/simplepie/SimplePie/Caption.php
vendored
131
inc/3rdparty/simplepie/SimplePie/Caption.php
vendored
@ -1,131 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Caption
|
||||
{
|
||||
var $type;
|
||||
var $lang;
|
||||
var $startTime;
|
||||
var $endTime;
|
||||
var $text;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->lang = $lang;
|
||||
$this->startTime = $startTime;
|
||||
$this->endTime = $endTime;
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_endtime()
|
||||
{
|
||||
if ($this->endTime !== null)
|
||||
{
|
||||
return $this->endTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_language()
|
||||
{
|
||||
if ($this->lang !== null)
|
||||
{
|
||||
return $this->lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_starttime()
|
||||
{
|
||||
if ($this->startTime !== null)
|
||||
{
|
||||
return $this->startTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_text()
|
||||
{
|
||||
if ($this->text !== null)
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_type()
|
||||
{
|
||||
if ($this->type !== null)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
103
inc/3rdparty/simplepie/SimplePie/Category.php
vendored
103
inc/3rdparty/simplepie/SimplePie/Category.php
vendored
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Category
|
||||
{
|
||||
var $term;
|
||||
var $scheme;
|
||||
var $label;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($term = null, $scheme = null, $label = null)
|
||||
{
|
||||
$this->term = $term;
|
||||
$this->scheme = $scheme;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_term()
|
||||
{
|
||||
if ($this->term !== null)
|
||||
{
|
||||
return $this->term;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_label()
|
||||
{
|
||||
if ($this->label !== null)
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->get_term();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,325 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Content-type sniffing
|
||||
*
|
||||
* Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Content_Type_Sniffer
|
||||
{
|
||||
/**
|
||||
* File object
|
||||
*
|
||||
* @var SimplePie_File
|
||||
*/
|
||||
var $file;
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input file
|
||||
*
|
||||
* @param SimplePie_Content_Type_Sniffer $file Input file
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Content-Type of the specified file
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
if (isset($this->file->headers['content-type']))
|
||||
{
|
||||
if (!isset($this->file->headers['content-encoding'])
|
||||
&& ($this->file->headers['content-type'] === 'text/plain'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
|
||||
{
|
||||
return $this->text_or_binary();
|
||||
}
|
||||
|
||||
if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
|
||||
{
|
||||
$official = substr($this->file->headers['content-type'], 0, $pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
$official = $this->file->headers['content-type'];
|
||||
}
|
||||
$official = trim(strtolower($official));
|
||||
|
||||
if ($official === 'unknown/unknown'
|
||||
|| $official === 'application/unknown')
|
||||
{
|
||||
return $this->unknown();
|
||||
}
|
||||
elseif (substr($official, -4) === '+xml'
|
||||
|| $official === 'text/xml'
|
||||
|| $official === 'application/xml')
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
elseif (substr($official, 0, 6) === 'image/')
|
||||
{
|
||||
if ($return = $this->image())
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
}
|
||||
elseif ($official === 'text/html')
|
||||
{
|
||||
return $this->feed_or_html();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->unknown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff text or binary
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function text_or_binary()
|
||||
{
|
||||
if (substr($this->file->body, 0, 2) === "\xFE\xFF"
|
||||
|| substr($this->file->body, 0, 2) === "\xFF\xFE"
|
||||
|| substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
|
||||
|| substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
|
||||
{
|
||||
return 'application/octect-stream';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff unknown
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function unknown()
|
||||
{
|
||||
$ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
|
||||
if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
|
||||
|| strtolower(substr($this->file->body, $ws, 5)) === '<html'
|
||||
|| strtolower(substr($this->file->body, $ws, 7)) === '<script')
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 5) === '%PDF-')
|
||||
{
|
||||
return 'application/pdf';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
|
||||
{
|
||||
return 'application/postscript';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 6) === 'GIF87a'
|
||||
|| substr($this->file->body, 0, 6) === 'GIF89a')
|
||||
{
|
||||
return 'image/gif';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
|
||||
{
|
||||
return 'image/jpeg';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
|
||||
{
|
||||
return 'image/bmp';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
|
||||
{
|
||||
return 'image/vnd.microsoft.icon';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->text_or_binary();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff images
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
if (substr($this->file->body, 0, 6) === 'GIF87a'
|
||||
|| substr($this->file->body, 0, 6) === 'GIF89a')
|
||||
{
|
||||
return 'image/gif';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
|
||||
{
|
||||
return 'image/jpeg';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
|
||||
{
|
||||
return 'image/bmp';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
|
||||
{
|
||||
return 'image/vnd.microsoft.icon';
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff HTML
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function feed_or_html()
|
||||
{
|
||||
$len = strlen($this->file->body);
|
||||
$pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
|
||||
|
||||
while ($pos < $len)
|
||||
{
|
||||
switch ($this->file->body[$pos])
|
||||
{
|
||||
case "\x09":
|
||||
case "\x0A":
|
||||
case "\x0D":
|
||||
case "\x20":
|
||||
$pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
|
||||
continue 2;
|
||||
|
||||
case '<':
|
||||
$pos++;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'text/html';
|
||||
}
|
||||
|
||||
if (substr($this->file->body, $pos, 3) === '!--')
|
||||
{
|
||||
$pos += 3;
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
|
||||
{
|
||||
$pos += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 1) === '!')
|
||||
{
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
|
||||
{
|
||||
$pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 1) === '?')
|
||||
{
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
|
||||
{
|
||||
$pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 3) === 'rss'
|
||||
|| substr($this->file->body, $pos, 7) === 'rdf:RDF')
|
||||
{
|
||||
return 'application/rss+xml';
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 4) === 'feed')
|
||||
{
|
||||
return 'application/atom+xml';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
|
||||
89
inc/3rdparty/simplepie/SimplePie/Copyright.php
vendored
89
inc/3rdparty/simplepie/SimplePie/Copyright.php
vendored
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Copyright
|
||||
{
|
||||
var $url;
|
||||
var $label;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($url = null, $label = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_url()
|
||||
{
|
||||
if ($this->url !== null)
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_attribution()
|
||||
{
|
||||
if ($this->label !== null)
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2838
inc/3rdparty/simplepie/SimplePie/Core.php
vendored
2838
inc/3rdparty/simplepie/SimplePie/Core.php
vendored
File diff suppressed because it is too large
Load Diff
103
inc/3rdparty/simplepie/SimplePie/Credit.php
vendored
103
inc/3rdparty/simplepie/SimplePie/Credit.php
vendored
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Credit
|
||||
{
|
||||
var $role;
|
||||
var $scheme;
|
||||
var $name;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($role = null, $scheme = null, $name = null)
|
||||
{
|
||||
$this->role = $role;
|
||||
$this->scheme = $scheme;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_role()
|
||||
{
|
||||
if ($this->role !== null)
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
if ($this->name !== null)
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
990
inc/3rdparty/simplepie/SimplePie/Enclosure.php
vendored
990
inc/3rdparty/simplepie/SimplePie/Enclosure.php
vendored
@ -1,990 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Enclosure
|
||||
{
|
||||
var $bitrate;
|
||||
var $captions;
|
||||
var $categories;
|
||||
var $channels;
|
||||
var $copyright;
|
||||
var $credits;
|
||||
var $description;
|
||||
var $duration;
|
||||
var $expression;
|
||||
var $framerate;
|
||||
var $handler;
|
||||
var $hashes;
|
||||
var $height;
|
||||
var $javascript;
|
||||
var $keywords;
|
||||
var $lang;
|
||||
var $length;
|
||||
var $link;
|
||||
var $medium;
|
||||
var $player;
|
||||
var $ratings;
|
||||
var $restrictions;
|
||||
var $samplingrate;
|
||||
var $thumbnails;
|
||||
var $title;
|
||||
var $type;
|
||||
var $width;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
|
||||
{
|
||||
$this->bitrate = $bitrate;
|
||||
$this->captions = $captions;
|
||||
$this->categories = $categories;
|
||||
$this->channels = $channels;
|
||||
$this->copyright = $copyright;
|
||||
$this->credits = $credits;
|
||||
$this->description = $description;
|
||||
$this->duration = $duration;
|
||||
$this->expression = $expression;
|
||||
$this->framerate = $framerate;
|
||||
$this->hashes = $hashes;
|
||||
$this->height = $height;
|
||||
$this->keywords = $keywords;
|
||||
$this->lang = $lang;
|
||||
$this->length = $length;
|
||||
$this->link = $link;
|
||||
$this->medium = $medium;
|
||||
$this->player = $player;
|
||||
$this->ratings = $ratings;
|
||||
$this->restrictions = $restrictions;
|
||||
$this->samplingrate = $samplingrate;
|
||||
$this->thumbnails = $thumbnails;
|
||||
$this->title = $title;
|
||||
$this->type = $type;
|
||||
$this->width = $width;
|
||||
|
||||
if (class_exists('idna_convert'))
|
||||
{
|
||||
$idn = new idna_convert();
|
||||
$parsed = SimplePie_Misc::parse_url($link);
|
||||
$this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
|
||||
}
|
||||
$this->handler = $this->get_handler(); // Needs to load last
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_bitrate()
|
||||
{
|
||||
if ($this->bitrate !== null)
|
||||
{
|
||||
return $this->bitrate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_caption($key = 0)
|
||||
{
|
||||
$captions = $this->get_captions();
|
||||
if (isset($captions[$key]))
|
||||
{
|
||||
return $captions[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_captions()
|
||||
{
|
||||
if ($this->captions !== null)
|
||||
{
|
||||
return $this->captions;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_category($key = 0)
|
||||
{
|
||||
$categories = $this->get_categories();
|
||||
if (isset($categories[$key]))
|
||||
{
|
||||
return $categories[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_categories()
|
||||
{
|
||||
if ($this->categories !== null)
|
||||
{
|
||||
return $this->categories;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_channels()
|
||||
{
|
||||
if ($this->channels !== null)
|
||||
{
|
||||
return $this->channels;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_copyright()
|
||||
{
|
||||
if ($this->copyright !== null)
|
||||
{
|
||||
return $this->copyright;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_credit($key = 0)
|
||||
{
|
||||
$credits = $this->get_credits();
|
||||
if (isset($credits[$key]))
|
||||
{
|
||||
return $credits[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_credits()
|
||||
{
|
||||
if ($this->credits !== null)
|
||||
{
|
||||
return $this->credits;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
if ($this->description !== null)
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_duration($convert = false)
|
||||
{
|
||||
if ($this->duration !== null)
|
||||
{
|
||||
if ($convert)
|
||||
{
|
||||
$time = SimplePie_Misc::time_hms($this->duration);
|
||||
return $time;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_expression()
|
||||
{
|
||||
if ($this->expression !== null)
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'full';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_extension()
|
||||
{
|
||||
if ($this->link !== null)
|
||||
{
|
||||
$url = SimplePie_Misc::parse_url($this->link);
|
||||
if ($url['path'] !== '')
|
||||
{
|
||||
return pathinfo($url['path'], PATHINFO_EXTENSION);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function get_framerate()
|
||||
{
|
||||
if ($this->framerate !== null)
|
||||
{
|
||||
return $this->framerate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_handler()
|
||||
{
|
||||
return $this->get_real_type(true);
|
||||
}
|
||||
|
||||
public function get_hash($key = 0)
|
||||
{
|
||||
$hashes = $this->get_hashes();
|
||||
if (isset($hashes[$key]))
|
||||
{
|
||||
return $hashes[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_hashes()
|
||||
{
|
||||
if ($this->hashes !== null)
|
||||
{
|
||||
return $this->hashes;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_height()
|
||||
{
|
||||
if ($this->height !== null)
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_language()
|
||||
{
|
||||
if ($this->lang !== null)
|
||||
{
|
||||
return $this->lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_keyword($key = 0)
|
||||
{
|
||||
$keywords = $this->get_keywords();
|
||||
if (isset($keywords[$key]))
|
||||
{
|
||||
return $keywords[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_keywords()
|
||||
{
|
||||
if ($this->keywords !== null)
|
||||
{
|
||||
return $this->keywords;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_length()
|
||||
{
|
||||
if ($this->length !== null)
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_link()
|
||||
{
|
||||
if ($this->link !== null)
|
||||
{
|
||||
return urldecode($this->link);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_medium()
|
||||
{
|
||||
if ($this->medium !== null)
|
||||
{
|
||||
return $this->medium;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_player()
|
||||
{
|
||||
if ($this->player !== null)
|
||||
{
|
||||
return $this->player;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_rating($key = 0)
|
||||
{
|
||||
$ratings = $this->get_ratings();
|
||||
if (isset($ratings[$key]))
|
||||
{
|
||||
return $ratings[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_ratings()
|
||||
{
|
||||
if ($this->ratings !== null)
|
||||
{
|
||||
return $this->ratings;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_restriction($key = 0)
|
||||
{
|
||||
$restrictions = $this->get_restrictions();
|
||||
if (isset($restrictions[$key]))
|
||||
{
|
||||
return $restrictions[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_restrictions()
|
||||
{
|
||||
if ($this->restrictions !== null)
|
||||
{
|
||||
return $this->restrictions;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_sampling_rate()
|
||||
{
|
||||
if ($this->samplingrate !== null)
|
||||
{
|
||||
return $this->samplingrate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_size()
|
||||
{
|
||||
$length = $this->get_length();
|
||||
if ($length !== null)
|
||||
{
|
||||
return round($length/1048576, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_thumbnail($key = 0)
|
||||
{
|
||||
$thumbnails = $this->get_thumbnails();
|
||||
if (isset($thumbnails[$key]))
|
||||
{
|
||||
return $thumbnails[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_thumbnails()
|
||||
{
|
||||
if ($this->thumbnails !== null)
|
||||
{
|
||||
return $this->thumbnails;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_title()
|
||||
{
|
||||
if ($this->title !== null)
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_type()
|
||||
{
|
||||
if ($this->type !== null)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_width()
|
||||
{
|
||||
if ($this->width !== null)
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function native_embed($options='')
|
||||
{
|
||||
return $this->embed($options, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
|
||||
*/
|
||||
public function embed($options = '', $native = false)
|
||||
{
|
||||
// Set up defaults
|
||||
$audio = '';
|
||||
$video = '';
|
||||
$alt = '';
|
||||
$altclass = '';
|
||||
$loop = 'false';
|
||||
$width = 'auto';
|
||||
$height = 'auto';
|
||||
$bgcolor = '#ffffff';
|
||||
$mediaplayer = '';
|
||||
$widescreen = false;
|
||||
$handler = $this->get_handler();
|
||||
$type = $this->get_real_type();
|
||||
|
||||
// Process options and reassign values as necessary
|
||||
if (is_array($options))
|
||||
{
|
||||
extract($options);
|
||||
}
|
||||
else
|
||||
{
|
||||
$options = explode(',', $options);
|
||||
foreach($options as $option)
|
||||
{
|
||||
$opt = explode(':', $option, 2);
|
||||
if (isset($opt[0], $opt[1]))
|
||||
{
|
||||
$opt[0] = trim($opt[0]);
|
||||
$opt[1] = trim($opt[1]);
|
||||
switch ($opt[0])
|
||||
{
|
||||
case 'audio':
|
||||
$audio = $opt[1];
|
||||
break;
|
||||
|
||||
case 'video':
|
||||
$video = $opt[1];
|
||||
break;
|
||||
|
||||
case 'alt':
|
||||
$alt = $opt[1];
|
||||
break;
|
||||
|
||||
case 'altclass':
|
||||
$altclass = $opt[1];
|
||||
break;
|
||||
|
||||
case 'loop':
|
||||
$loop = $opt[1];
|
||||
break;
|
||||
|
||||
case 'width':
|
||||
$width = $opt[1];
|
||||
break;
|
||||
|
||||
case 'height':
|
||||
$height = $opt[1];
|
||||
break;
|
||||
|
||||
case 'bgcolor':
|
||||
$bgcolor = $opt[1];
|
||||
break;
|
||||
|
||||
case 'mediaplayer':
|
||||
$mediaplayer = $opt[1];
|
||||
break;
|
||||
|
||||
case 'widescreen':
|
||||
$widescreen = $opt[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mime = explode('/', $type, 2);
|
||||
$mime = $mime[0];
|
||||
|
||||
// Process values for 'auto'
|
||||
if ($width === 'auto')
|
||||
{
|
||||
if ($mime === 'video')
|
||||
{
|
||||
if ($height === 'auto')
|
||||
{
|
||||
$width = 480;
|
||||
}
|
||||
elseif ($widescreen)
|
||||
{
|
||||
$width = round((intval($height)/9)*16);
|
||||
}
|
||||
else
|
||||
{
|
||||
$width = round((intval($height)/3)*4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$width = '100%';
|
||||
}
|
||||
}
|
||||
|
||||
if ($height === 'auto')
|
||||
{
|
||||
if ($mime === 'audio')
|
||||
{
|
||||
$height = 0;
|
||||
}
|
||||
elseif ($mime === 'video')
|
||||
{
|
||||
if ($width === 'auto')
|
||||
{
|
||||
if ($widescreen)
|
||||
{
|
||||
$height = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
$height = 360;
|
||||
}
|
||||
}
|
||||
elseif ($widescreen)
|
||||
{
|
||||
$height = round((intval($width)/16)*9);
|
||||
}
|
||||
else
|
||||
{
|
||||
$height = round((intval($width)/4)*3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$height = 376;
|
||||
}
|
||||
}
|
||||
elseif ($mime === 'audio')
|
||||
{
|
||||
$height = 0;
|
||||
}
|
||||
|
||||
// Set proper placeholder value
|
||||
if ($mime === 'audio')
|
||||
{
|
||||
$placeholder = $audio;
|
||||
}
|
||||
elseif ($mime === 'video')
|
||||
{
|
||||
$placeholder = $video;
|
||||
}
|
||||
|
||||
$embed = '';
|
||||
|
||||
// Odeo Feed MP3's
|
||||
if ($handler === 'odeo')
|
||||
{
|
||||
if ($native)
|
||||
{
|
||||
$embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
|
||||
}
|
||||
}
|
||||
|
||||
// Flash
|
||||
elseif ($handler === 'flash')
|
||||
{
|
||||
if ($native)
|
||||
{
|
||||
$embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
|
||||
}
|
||||
}
|
||||
|
||||
// Flash Media Player file types.
|
||||
// Preferred handler for MP3 file types.
|
||||
elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
|
||||
{
|
||||
$height += 20;
|
||||
if ($native)
|
||||
{
|
||||
$embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
|
||||
}
|
||||
}
|
||||
|
||||
// QuickTime 7 file types. Need to test with QuickTime 6.
|
||||
// Only handle MP3's if the Flash Media Player is not present.
|
||||
elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
|
||||
{
|
||||
$height += 16;
|
||||
if ($native)
|
||||
{
|
||||
if ($placeholder !== '')
|
||||
{
|
||||
$embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
|
||||
}
|
||||
}
|
||||
|
||||
// Windows Media
|
||||
elseif ($handler === 'wmedia')
|
||||
{
|
||||
$height += 45;
|
||||
if ($native)
|
||||
{
|
||||
$embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
|
||||
}
|
||||
}
|
||||
|
||||
// Everything else
|
||||
else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
|
||||
|
||||
return $embed;
|
||||
}
|
||||
|
||||
public function get_real_type($find_handler = false)
|
||||
{
|
||||
// If it's Odeo, let's get it out of the way.
|
||||
if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
|
||||
{
|
||||
return 'odeo';
|
||||
}
|
||||
|
||||
// Mime-types by handler.
|
||||
$types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
|
||||
$types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
|
||||
$types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
|
||||
$types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
|
||||
$types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
|
||||
|
||||
if ($this->get_type() !== null)
|
||||
{
|
||||
$type = strtolower($this->type);
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = null;
|
||||
}
|
||||
|
||||
// If we encounter an unsupported mime-type, check the file extension and guess intelligently.
|
||||
if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
|
||||
{
|
||||
switch (strtolower($this->get_extension()))
|
||||
{
|
||||
// Audio mime-types
|
||||
case 'aac':
|
||||
case 'adts':
|
||||
$type = 'audio/acc';
|
||||
break;
|
||||
|
||||
case 'aif':
|
||||
case 'aifc':
|
||||
case 'aiff':
|
||||
case 'cdda':
|
||||
$type = 'audio/aiff';
|
||||
break;
|
||||
|
||||
case 'bwf':
|
||||
$type = 'audio/wav';
|
||||
break;
|
||||
|
||||
case 'kar':
|
||||
case 'mid':
|
||||
case 'midi':
|
||||
case 'smf':
|
||||
$type = 'audio/midi';
|
||||
break;
|
||||
|
||||
case 'm4a':
|
||||
$type = 'audio/x-m4a';
|
||||
break;
|
||||
|
||||
case 'mp3':
|
||||
case 'swa':
|
||||
$type = 'audio/mp3';
|
||||
break;
|
||||
|
||||
case 'wav':
|
||||
$type = 'audio/wav';
|
||||
break;
|
||||
|
||||
case 'wax':
|
||||
$type = 'audio/x-ms-wax';
|
||||
break;
|
||||
|
||||
case 'wma':
|
||||
$type = 'audio/x-ms-wma';
|
||||
break;
|
||||
|
||||
// Video mime-types
|
||||
case '3gp':
|
||||
case '3gpp':
|
||||
$type = 'video/3gpp';
|
||||
break;
|
||||
|
||||
case '3g2':
|
||||
case '3gp2':
|
||||
$type = 'video/3gpp2';
|
||||
break;
|
||||
|
||||
case 'asf':
|
||||
$type = 'video/x-ms-asf';
|
||||
break;
|
||||
|
||||
case 'flv':
|
||||
$type = 'video/x-flv';
|
||||
break;
|
||||
|
||||
case 'm1a':
|
||||
case 'm1s':
|
||||
case 'm1v':
|
||||
case 'm15':
|
||||
case 'm75':
|
||||
case 'mp2':
|
||||
case 'mpa':
|
||||
case 'mpeg':
|
||||
case 'mpg':
|
||||
case 'mpm':
|
||||
case 'mpv':
|
||||
$type = 'video/mpeg';
|
||||
break;
|
||||
|
||||
case 'm4v':
|
||||
$type = 'video/x-m4v';
|
||||
break;
|
||||
|
||||
case 'mov':
|
||||
case 'qt':
|
||||
$type = 'video/quicktime';
|
||||
break;
|
||||
|
||||
case 'mp4':
|
||||
case 'mpg4':
|
||||
$type = 'video/mp4';
|
||||
break;
|
||||
|
||||
case 'sdv':
|
||||
$type = 'video/sd-video';
|
||||
break;
|
||||
|
||||
case 'wm':
|
||||
$type = 'video/x-ms-wm';
|
||||
break;
|
||||
|
||||
case 'wmv':
|
||||
$type = 'video/x-ms-wmv';
|
||||
break;
|
||||
|
||||
case 'wvx':
|
||||
$type = 'video/x-ms-wvx';
|
||||
break;
|
||||
|
||||
// Flash mime-types
|
||||
case 'spl':
|
||||
$type = 'application/futuresplash';
|
||||
break;
|
||||
|
||||
case 'swf':
|
||||
$type = 'application/x-shockwave-flash';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($find_handler)
|
||||
{
|
||||
if (in_array($type, $types_flash))
|
||||
{
|
||||
return 'flash';
|
||||
}
|
||||
elseif (in_array($type, $types_fmedia))
|
||||
{
|
||||
return 'fmedia';
|
||||
}
|
||||
elseif (in_array($type, $types_quicktime))
|
||||
{
|
||||
return 'quicktime';
|
||||
}
|
||||
elseif (in_array($type, $types_wmedia))
|
||||
{
|
||||
return 'wmedia';
|
||||
}
|
||||
elseif (in_array($type, $types_mp3))
|
||||
{
|
||||
return 'mp3';
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
278
inc/3rdparty/simplepie/SimplePie/File.php
vendored
278
inc/3rdparty/simplepie/SimplePie/File.php
vendored
@ -1,278 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @todo Move to properly supporting RFC2616 (HTTP/1.1)
|
||||
*/
|
||||
class SimplePie_File
|
||||
{
|
||||
var $url;
|
||||
var $useragent;
|
||||
var $success = true;
|
||||
var $headers = array();
|
||||
var $body;
|
||||
var $status_code;
|
||||
var $redirects = 0;
|
||||
var $error;
|
||||
var $method = SIMPLEPIE_FILE_SOURCE_NONE;
|
||||
|
||||
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
|
||||
{
|
||||
if (class_exists('idna_convert'))
|
||||
{
|
||||
$idn = new idna_convert();
|
||||
$parsed = SimplePie_Misc::parse_url($url);
|
||||
$url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
|
||||
}
|
||||
$this->url = $url;
|
||||
$this->useragent = $useragent;
|
||||
if (preg_match('/^http(s)?:\/\//i', $url))
|
||||
{
|
||||
if ($useragent === null)
|
||||
{
|
||||
$useragent = ini_get('user_agent');
|
||||
$this->useragent = $useragent;
|
||||
}
|
||||
if (!is_array($headers))
|
||||
{
|
||||
$headers = array();
|
||||
}
|
||||
if (!$force_fsockopen && function_exists('curl_exec'))
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
|
||||
$fp = curl_init();
|
||||
$headers2 = array();
|
||||
foreach ($headers as $key => $value)
|
||||
{
|
||||
$headers2[] = "$key: $value";
|
||||
}
|
||||
if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_ENCODING, '');
|
||||
}
|
||||
curl_setopt($fp, CURLOPT_URL, $url);
|
||||
curl_setopt($fp, CURLOPT_HEADER, 1);
|
||||
curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
curl_setopt($fp, CURLOPT_REFERER, $url);
|
||||
curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
|
||||
curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
|
||||
if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
|
||||
}
|
||||
|
||||
$this->headers = curl_exec($fp);
|
||||
if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_ENCODING, 'none');
|
||||
$this->headers = curl_exec($fp);
|
||||
}
|
||||
if (curl_errno($fp))
|
||||
{
|
||||
$this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$info = curl_getinfo($fp);
|
||||
curl_close($fp);
|
||||
$this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
|
||||
$this->headers = array_pop($this->headers);
|
||||
$parser = new SimplePie_HTTP_Parser($this->headers);
|
||||
if ($parser->parse())
|
||||
{
|
||||
$this->headers = $parser->headers;
|
||||
$this->body = $parser->body;
|
||||
$this->status_code = $parser->status_code;
|
||||
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
|
||||
{
|
||||
$this->redirects++;
|
||||
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
|
||||
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
|
||||
$url_parts = parse_url($url);
|
||||
$socket_host = $url_parts['host'];
|
||||
if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
|
||||
{
|
||||
$socket_host = "ssl://$url_parts[host]";
|
||||
$url_parts['port'] = 443;
|
||||
}
|
||||
if (!isset($url_parts['port']))
|
||||
{
|
||||
$url_parts['port'] = 80;
|
||||
}
|
||||
$fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
|
||||
if (!$fp)
|
||||
{
|
||||
$this->error = 'fsockopen error: ' . $errstr;
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_set_timeout($fp, $timeout);
|
||||
if (isset($url_parts['path']))
|
||||
{
|
||||
if (isset($url_parts['query']))
|
||||
{
|
||||
$get = "$url_parts[path]?$url_parts[query]";
|
||||
}
|
||||
else
|
||||
{
|
||||
$get = $url_parts['path'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$get = '/';
|
||||
}
|
||||
$out = "GET $get HTTP/1.1\r\n";
|
||||
$out .= "Host: $url_parts[host]\r\n";
|
||||
$out .= "User-Agent: $useragent\r\n";
|
||||
if (extension_loaded('zlib'))
|
||||
{
|
||||
$out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
|
||||
}
|
||||
|
||||
if (isset($url_parts['user']) && isset($url_parts['pass']))
|
||||
{
|
||||
$out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
|
||||
}
|
||||
foreach ($headers as $key => $value)
|
||||
{
|
||||
$out .= "$key: $value\r\n";
|
||||
}
|
||||
$out .= "Connection: Close\r\n\r\n";
|
||||
fwrite($fp, $out);
|
||||
|
||||
$info = stream_get_meta_data($fp);
|
||||
|
||||
$this->headers = '';
|
||||
while (!$info['eof'] && !$info['timed_out'])
|
||||
{
|
||||
$this->headers .= fread($fp, 1160);
|
||||
$info = stream_get_meta_data($fp);
|
||||
}
|
||||
if (!$info['timed_out'])
|
||||
{
|
||||
$parser = new SimplePie_HTTP_Parser($this->headers);
|
||||
if ($parser->parse())
|
||||
{
|
||||
$this->headers = $parser->headers;
|
||||
$this->body = $parser->body;
|
||||
$this->status_code = $parser->status_code;
|
||||
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
|
||||
{
|
||||
$this->redirects++;
|
||||
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
|
||||
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
|
||||
}
|
||||
if (isset($this->headers['content-encoding']))
|
||||
{
|
||||
// Hey, we act dumb elsewhere, so let's do that here too
|
||||
switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
|
||||
{
|
||||
case 'gzip':
|
||||
case 'x-gzip':
|
||||
$decoder = new SimplePie_gzdecode($this->body);
|
||||
if (!$decoder->parse())
|
||||
{
|
||||
$this->error = 'Unable to decode HTTP "gzip" stream';
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->body = $decoder->data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deflate':
|
||||
if (($body = gzuncompress($this->body)) === false)
|
||||
{
|
||||
if (($body = gzinflate($this->body)) === false)
|
||||
{
|
||||
$this->error = 'Unable to decode HTTP "deflate" stream';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
$this->body = $body;
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->error = 'Unknown content coding';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error = 'fsocket timed out';
|
||||
$this->success = false;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
|
||||
if (!$this->body = file_get_contents($url))
|
||||
{
|
||||
$this->error = 'file_get_contents could not read the file';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
492
inc/3rdparty/simplepie/SimplePie/HTTP/Parser.php
vendored
492
inc/3rdparty/simplepie/SimplePie/HTTP/Parser.php
vendored
@ -1,492 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* HTTP Response Parser
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_HTTP_Parser
|
||||
{
|
||||
/**
|
||||
* HTTP Version
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $http_version = 0.0;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $status_code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $reason = '';
|
||||
|
||||
/**
|
||||
* Key/value pairs of the headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Body of the response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Current state of the state machine
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $state = 'http_version';
|
||||
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $data = '';
|
||||
|
||||
/**
|
||||
* Input data length (to avoid calling strlen() everytime this is needed)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $data_length = 0;
|
||||
|
||||
/**
|
||||
* Current position of the pointer
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Name of the hedaer currently being parsed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* Value of the hedaer currently being parsed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value = '';
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input data
|
||||
*
|
||||
* @param string $data Input data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->data_length = strlen($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input data
|
||||
*
|
||||
* @return bool true on success, false on failure
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
while ($this->state && $this->state !== 'emit' && $this->has_data())
|
||||
{
|
||||
$state = $this->state;
|
||||
$this->$state();
|
||||
}
|
||||
$this->data = '';
|
||||
if ($this->state === 'emit' || $this->state === 'body')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->http_version = '';
|
||||
$this->status_code = '';
|
||||
$this->reason = '';
|
||||
$this->headers = array();
|
||||
$this->body = '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is data beyond the pointer
|
||||
*
|
||||
* @return bool true if there is further data, false if not
|
||||
*/
|
||||
protected function has_data()
|
||||
{
|
||||
return (bool) ($this->position < $this->data_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the next character is LWS
|
||||
*
|
||||
* @return bool true if the next character is LWS, false if not
|
||||
*/
|
||||
protected function is_linear_whitespace()
|
||||
{
|
||||
return (bool) ($this->data[$this->position] === "\x09"
|
||||
|| $this->data[$this->position] === "\x20"
|
||||
|| ($this->data[$this->position] === "\x0A"
|
||||
&& isset($this->data[$this->position + 1])
|
||||
&& ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the HTTP version
|
||||
*/
|
||||
protected function http_version()
|
||||
{
|
||||
if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
|
||||
{
|
||||
$len = strspn($this->data, '0123456789.', 5);
|
||||
$this->http_version = substr($this->data, 5, $len);
|
||||
$this->position += 5 + $len;
|
||||
if (substr_count($this->http_version, '.') <= 1)
|
||||
{
|
||||
$this->http_version = (float) $this->http_version;
|
||||
$this->position += strspn($this->data, "\x09\x20", $this->position);
|
||||
$this->state = 'status';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the status code
|
||||
*/
|
||||
protected function status()
|
||||
{
|
||||
if ($len = strspn($this->data, '0123456789', $this->position))
|
||||
{
|
||||
$this->status_code = (int) substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'reason';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the reason phrase
|
||||
*/
|
||||
protected function reason()
|
||||
{
|
||||
$len = strcspn($this->data, "\x0A", $this->position);
|
||||
$this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
|
||||
$this->position += $len + 1;
|
||||
$this->state = 'new_line';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal with a new line, shifting data around as needed
|
||||
*/
|
||||
protected function new_line()
|
||||
{
|
||||
$this->value = trim($this->value, "\x0D\x20");
|
||||
if ($this->name !== '' && $this->value !== '')
|
||||
{
|
||||
$this->name = strtolower($this->name);
|
||||
// We should only use the last Content-Type header. c.f. issue #1
|
||||
if (isset($this->headers[$this->name]) && $this->name !== 'content-type')
|
||||
{
|
||||
$this->headers[$this->name] .= ', ' . $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->headers[$this->name] = $this->value;
|
||||
}
|
||||
}
|
||||
$this->name = '';
|
||||
$this->value = '';
|
||||
if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
|
||||
{
|
||||
$this->position += 2;
|
||||
$this->state = 'body';
|
||||
}
|
||||
elseif ($this->data[$this->position] === "\x0A")
|
||||
{
|
||||
$this->position++;
|
||||
$this->state = 'body';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'name';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header name
|
||||
*/
|
||||
protected function name()
|
||||
{
|
||||
$len = strcspn($this->data, "\x0A:", $this->position);
|
||||
if (isset($this->data[$this->position + $len]))
|
||||
{
|
||||
if ($this->data[$this->position + $len] === "\x0A")
|
||||
{
|
||||
$this->position += $len;
|
||||
$this->state = 'new_line';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->name = substr($this->data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
$this->state = 'value';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse LWS, replacing consecutive LWS characters with a single space
|
||||
*/
|
||||
protected function linear_whitespace()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (substr($this->data, $this->position, 2) === "\x0D\x0A")
|
||||
{
|
||||
$this->position += 2;
|
||||
}
|
||||
elseif ($this->data[$this->position] === "\x0A")
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
$this->position += strspn($this->data, "\x09\x20", $this->position);
|
||||
} while ($this->has_data() && $this->is_linear_whitespace());
|
||||
$this->value .= "\x20";
|
||||
}
|
||||
|
||||
/**
|
||||
* See what state to move to while within non-quoted header values
|
||||
*/
|
||||
protected function value()
|
||||
{
|
||||
if ($this->is_linear_whitespace())
|
||||
{
|
||||
$this->linear_whitespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($this->data[$this->position])
|
||||
{
|
||||
case '"':
|
||||
// Workaround for ETags: we have to include the quotes as
|
||||
// part of the tag.
|
||||
if (strtolower($this->name) === 'etag')
|
||||
{
|
||||
$this->value .= '"';
|
||||
$this->position++;
|
||||
$this->state = 'value_char';
|
||||
break;
|
||||
}
|
||||
$this->position++;
|
||||
$this->state = 'quote';
|
||||
break;
|
||||
|
||||
case "\x0A":
|
||||
$this->position++;
|
||||
$this->state = 'new_line';
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = 'value_char';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header value while outside quotes
|
||||
*/
|
||||
protected function value_char()
|
||||
{
|
||||
$len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
|
||||
$this->value .= substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'value';
|
||||
}
|
||||
|
||||
/**
|
||||
* See what state to move to while within quoted header values
|
||||
*/
|
||||
protected function quote()
|
||||
{
|
||||
if ($this->is_linear_whitespace())
|
||||
{
|
||||
$this->linear_whitespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($this->data[$this->position])
|
||||
{
|
||||
case '"':
|
||||
$this->position++;
|
||||
$this->state = 'value';
|
||||
break;
|
||||
|
||||
case "\x0A":
|
||||
$this->position++;
|
||||
$this->state = 'new_line';
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
$this->position++;
|
||||
$this->state = 'quote_escaped';
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = 'quote_char';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header value while within quotes
|
||||
*/
|
||||
protected function quote_char()
|
||||
{
|
||||
$len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
|
||||
$this->value .= substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'value';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an escaped character within quotes
|
||||
*/
|
||||
protected function quote_escaped()
|
||||
{
|
||||
$this->value .= $this->data[$this->position];
|
||||
$this->position++;
|
||||
$this->state = 'quote';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the body
|
||||
*/
|
||||
protected function body()
|
||||
{
|
||||
$this->body = substr($this->data, $this->position);
|
||||
if (!empty($this->headers['transfer-encoding']))
|
||||
{
|
||||
unset($this->headers['transfer-encoding']);
|
||||
$this->state = 'chunked';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed a "Transfer-Encoding: chunked" body
|
||||
*/
|
||||
protected function chunked()
|
||||
{
|
||||
if (!preg_match('/^[0-9a-f]+(\s|\r|\n)+/mi', trim($this->body)))
|
||||
{
|
||||
$this->state = 'emit';
|
||||
return;
|
||||
}
|
||||
|
||||
$decoded = '';
|
||||
$encoded = $this->body;
|
||||
|
||||
while (true)
|
||||
{
|
||||
$is_chunked = (bool) preg_match( '/^([0-9a-f]+)(\s|\r|\n)+/mi', $encoded, $matches );
|
||||
if (!$is_chunked)
|
||||
{
|
||||
// Looks like it's not chunked after all
|
||||
$this->state = 'emit';
|
||||
return;
|
||||
}
|
||||
|
||||
$length = hexdec($matches[1]);
|
||||
$chunk_length = strlen($matches[0]);
|
||||
$decoded .= $part = substr($encoded, $chunk_length, $length);
|
||||
$encoded = ltrim(substr($encoded, $chunk_length + $length), "\r\n");
|
||||
|
||||
if (trim($encoded) === '0')
|
||||
{
|
||||
$this->state = 'emit';
|
||||
$this->body = $decoded;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
997
inc/3rdparty/simplepie/SimplePie/IRI.php
vendored
997
inc/3rdparty/simplepie/SimplePie/IRI.php
vendored
@ -1,997 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
/**
|
||||
* IRI parser/serialiser
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_IRI
|
||||
{
|
||||
/**
|
||||
* Scheme
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $scheme;
|
||||
|
||||
/**
|
||||
* User Information
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $userinfo;
|
||||
|
||||
/**
|
||||
* Host
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $host;
|
||||
|
||||
/**
|
||||
* Port
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $port;
|
||||
|
||||
/**
|
||||
* Path
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $path;
|
||||
|
||||
/**
|
||||
* Query
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $query;
|
||||
|
||||
/**
|
||||
* Fragment
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $fragment;
|
||||
|
||||
/**
|
||||
* Whether the object represents a valid IRI
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $valid = array();
|
||||
|
||||
/**
|
||||
* Return the entire IRI when you try and read the object as a string
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->get_iri();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IRI object, from a specified string
|
||||
*
|
||||
* @access public
|
||||
* @param string $iri
|
||||
* @return SimplePie_IRI
|
||||
*/
|
||||
public function __construct($iri)
|
||||
{
|
||||
$iri = (string) $iri;
|
||||
if ($iri !== '')
|
||||
{
|
||||
$parsed = $this->parse_iri($iri);
|
||||
$this->set_scheme($parsed['scheme']);
|
||||
$this->set_authority($parsed['authority']);
|
||||
$this->set_path($parsed['path']);
|
||||
$this->set_query($parsed['query']);
|
||||
$this->set_fragment($parsed['fragment']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IRI object by resolving a relative IRI
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param SimplePie_IRI $base Base IRI
|
||||
* @param string $relative Relative IRI
|
||||
* @return SimplePie_IRI
|
||||
*/
|
||||
public static function absolutize($base, $relative)
|
||||
{
|
||||
$relative = (string) $relative;
|
||||
if ($relative !== '')
|
||||
{
|
||||
$relative = new SimplePie_IRI($relative);
|
||||
if ($relative->get_scheme() !== null)
|
||||
{
|
||||
$target = $relative;
|
||||
}
|
||||
elseif ($base->get_iri() !== null)
|
||||
{
|
||||
if ($relative->get_authority() !== null)
|
||||
{
|
||||
$target = $relative;
|
||||
$target->set_scheme($base->get_scheme());
|
||||
}
|
||||
else
|
||||
{
|
||||
$target = new SimplePie_IRI('');
|
||||
$target->set_scheme($base->get_scheme());
|
||||
$target->set_userinfo($base->get_userinfo());
|
||||
$target->set_host($base->get_host());
|
||||
$target->set_port($base->get_port());
|
||||
if ($relative->get_path() !== null)
|
||||
{
|
||||
if (strpos($relative->get_path(), '/') === 0)
|
||||
{
|
||||
$target->set_path($relative->get_path());
|
||||
}
|
||||
elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
|
||||
{
|
||||
$target->set_path('/' . $relative->get_path());
|
||||
}
|
||||
elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
|
||||
{
|
||||
$target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
|
||||
}
|
||||
else
|
||||
{
|
||||
$target->set_path($relative->get_path());
|
||||
}
|
||||
$target->set_query($relative->get_query());
|
||||
}
|
||||
else
|
||||
{
|
||||
$target->set_path($base->get_path());
|
||||
if ($relative->get_query() !== null)
|
||||
{
|
||||
$target->set_query($relative->get_query());
|
||||
}
|
||||
elseif ($base->get_query() !== null)
|
||||
{
|
||||
$target->set_query($base->get_query());
|
||||
}
|
||||
}
|
||||
}
|
||||
$target->set_fragment($relative->get_fragment());
|
||||
}
|
||||
else
|
||||
{
|
||||
// No base URL, just return the relative URL
|
||||
$target = $relative;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$target = $base;
|
||||
}
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an IRI into scheme/authority/path/query/fragment segments
|
||||
*
|
||||
* @access private
|
||||
* @param string $iri
|
||||
* @return array
|
||||
*/
|
||||
public function parse_iri($iri)
|
||||
{
|
||||
preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
|
||||
for ($i = count($match); $i <= 9; $i++)
|
||||
{
|
||||
$match[$i] = '';
|
||||
}
|
||||
return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove dot segments from a path
|
||||
*
|
||||
* @access private
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public function remove_dot_segments($input)
|
||||
{
|
||||
$output = '';
|
||||
while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
|
||||
{
|
||||
// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
|
||||
if (strpos($input, '../') === 0)
|
||||
{
|
||||
$input = substr($input, 3);
|
||||
}
|
||||
elseif (strpos($input, './') === 0)
|
||||
{
|
||||
$input = substr($input, 2);
|
||||
}
|
||||
// B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
|
||||
elseif (strpos($input, '/./') === 0)
|
||||
{
|
||||
$input = substr_replace($input, '/', 0, 3);
|
||||
}
|
||||
elseif ($input === '/.')
|
||||
{
|
||||
$input = '/';
|
||||
}
|
||||
// C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
|
||||
elseif (strpos($input, '/../') === 0)
|
||||
{
|
||||
$input = substr_replace($input, '/', 0, 4);
|
||||
$output = substr_replace($output, '', strrpos($output, '/'));
|
||||
}
|
||||
elseif ($input === '/..')
|
||||
{
|
||||
$input = '/';
|
||||
$output = substr_replace($output, '', strrpos($output, '/'));
|
||||
}
|
||||
// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
|
||||
elseif ($input === '.' || $input === '..')
|
||||
{
|
||||
$input = '';
|
||||
}
|
||||
// E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
|
||||
elseif (($pos = strpos($input, '/', 1)) !== false)
|
||||
{
|
||||
$output .= substr($input, 0, $pos);
|
||||
$input = substr_replace($input, '', 0, $pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= $input;
|
||||
$input = '';
|
||||
}
|
||||
}
|
||||
return $output . $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace invalid character with percent encoding
|
||||
*
|
||||
* @param string $string Input string
|
||||
* @param string $valid_chars Valid characters not in iunreserved or iprivate (this is ASCII-only)
|
||||
* @param int $case Normalise case
|
||||
* @param bool $iprivate Allow iprivate
|
||||
* @return string
|
||||
*/
|
||||
protected function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)
|
||||
{
|
||||
// Normalize as many pct-encoded sections as possible
|
||||
$string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
|
||||
|
||||
// Replace invalid percent characters
|
||||
$string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
|
||||
|
||||
// Add unreserved and % to $valid_chars (the latter is safe because all
|
||||
// pct-encoded sections are now valid).
|
||||
$valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
|
||||
|
||||
// Now replace any bytes that aren't allowed with their pct-encoded versions
|
||||
$position = 0;
|
||||
$strlen = strlen($string);
|
||||
while (($position += strspn($string, $valid_chars, $position)) < $strlen)
|
||||
{
|
||||
$value = ord($string[$position]);
|
||||
|
||||
// Start position
|
||||
$start = $position;
|
||||
|
||||
// By default we are valid
|
||||
$valid = true;
|
||||
|
||||
// No one byte sequences are valid due to the while.
|
||||
// Two byte sequence:
|
||||
if (($value & 0xE0) === 0xC0)
|
||||
{
|
||||
$character = ($value & 0x1F) << 6;
|
||||
$length = 2;
|
||||
$remaining = 1;
|
||||
}
|
||||
// Three byte sequence:
|
||||
elseif (($value & 0xF0) === 0xE0)
|
||||
{
|
||||
$character = ($value & 0x0F) << 12;
|
||||
$length = 3;
|
||||
$remaining = 2;
|
||||
}
|
||||
// Four byte sequence:
|
||||
elseif (($value & 0xF8) === 0xF0)
|
||||
{
|
||||
$character = ($value & 0x07) << 18;
|
||||
$length = 4;
|
||||
$remaining = 3;
|
||||
}
|
||||
// Invalid byte:
|
||||
else
|
||||
{
|
||||
$valid = false;
|
||||
$length = 1;
|
||||
$remaining = 0;
|
||||
}
|
||||
|
||||
if ($remaining)
|
||||
{
|
||||
if ($position + $length <= $strlen)
|
||||
{
|
||||
for ($position++; $remaining; $position++)
|
||||
{
|
||||
$value = ord($string[$position]);
|
||||
|
||||
// Check that the byte is valid, then add it to the character:
|
||||
if (($value & 0xC0) === 0x80)
|
||||
{
|
||||
$character |= ($value & 0x3F) << (--$remaining * 6);
|
||||
}
|
||||
// If it is invalid, count the sequence as invalid and reprocess the current byte:
|
||||
else
|
||||
{
|
||||
$valid = false;
|
||||
$position--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$position = $strlen - 1;
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Percent encode anything invalid or not in ucschar
|
||||
if (
|
||||
// Invalid sequences
|
||||
!$valid
|
||||
// Non-shortest form sequences are invalid
|
||||
|| $length > 1 && $character <= 0x7F
|
||||
|| $length > 2 && $character <= 0x7FF
|
||||
|| $length > 3 && $character <= 0xFFFF
|
||||
// Outside of range of ucschar codepoints
|
||||
// Noncharacters
|
||||
|| ($character & 0xFFFE) === 0xFFFE
|
||||
|| $character >= 0xFDD0 && $character <= 0xFDEF
|
||||
|| (
|
||||
// Everything else not in ucschar
|
||||
$character > 0xD7FF && $character < 0xF900
|
||||
|| $character < 0xA0
|
||||
|| $character > 0xEFFFD
|
||||
)
|
||||
&& (
|
||||
// Everything not in iprivate, if it applies
|
||||
!$iprivate
|
||||
|| $character < 0xE000
|
||||
|| $character > 0x10FFFD
|
||||
)
|
||||
)
|
||||
{
|
||||
// If we were a character, pretend we weren't, but rather an error.
|
||||
if ($valid)
|
||||
$position--;
|
||||
|
||||
for ($j = $start; $j <= $position; $j++)
|
||||
{
|
||||
$string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
|
||||
$j += 2;
|
||||
$position += 2;
|
||||
$strlen += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalise case
|
||||
if ($case & SIMPLEPIE_LOWERCASE)
|
||||
{
|
||||
$string = strtolower($string);
|
||||
}
|
||||
elseif ($case & SIMPLEPIE_UPPERCASE)
|
||||
{
|
||||
$string = strtoupper($string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for preg_replace_callback.
|
||||
*
|
||||
* Removes sequences of percent encoded bytes that represent UTF-8
|
||||
* encoded characters in iunreserved
|
||||
*
|
||||
* @param array $match PCRE match
|
||||
* @return string Replacement
|
||||
*/
|
||||
protected function remove_iunreserved_percent_encoded($match)
|
||||
{
|
||||
// As we just have valid percent encoded sequences we can just explode
|
||||
// and ignore the first member of the returned array (an empty string).
|
||||
$bytes = explode('%', $match[0]);
|
||||
|
||||
// Initialize the new string (this is what will be returned) and that
|
||||
// there are no bytes remaining in the current sequence (unsurprising
|
||||
// at the first byte!).
|
||||
$string = '';
|
||||
$remaining = 0;
|
||||
|
||||
// Loop over each and every byte, and set $value to its value
|
||||
for ($i = 1, $len = count($bytes); $i < $len; $i++)
|
||||
{
|
||||
$value = hexdec($bytes[$i]);
|
||||
|
||||
// If we're the first byte of sequence:
|
||||
if (!$remaining)
|
||||
{
|
||||
// Start position
|
||||
$start = $i;
|
||||
|
||||
// By default we are valid
|
||||
$valid = true;
|
||||
|
||||
// One byte sequence:
|
||||
if ($value <= 0x7F)
|
||||
{
|
||||
$character = $value;
|
||||
$length = 1;
|
||||
}
|
||||
// Two byte sequence:
|
||||
elseif (($value & 0xE0) === 0xC0)
|
||||
{
|
||||
$character = ($value & 0x1F) << 6;
|
||||
$length = 2;
|
||||
$remaining = 1;
|
||||
}
|
||||
// Three byte sequence:
|
||||
elseif (($value & 0xF0) === 0xE0)
|
||||
{
|
||||
$character = ($value & 0x0F) << 12;
|
||||
$length = 3;
|
||||
$remaining = 2;
|
||||
}
|
||||
// Four byte sequence:
|
||||
elseif (($value & 0xF8) === 0xF0)
|
||||
{
|
||||
$character = ($value & 0x07) << 18;
|
||||
$length = 4;
|
||||
$remaining = 3;
|
||||
}
|
||||
// Invalid byte:
|
||||
else
|
||||
{
|
||||
$valid = false;
|
||||
$remaining = 0;
|
||||
}
|
||||
}
|
||||
// Continuation byte:
|
||||
else
|
||||
{
|
||||
// Check that the byte is valid, then add it to the character:
|
||||
if (($value & 0xC0) === 0x80)
|
||||
{
|
||||
$remaining--;
|
||||
$character |= ($value & 0x3F) << ($remaining * 6);
|
||||
}
|
||||
// If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
|
||||
else
|
||||
{
|
||||
$valid = false;
|
||||
$remaining = 0;
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've reached the end of the current byte sequence, append it to Unicode::$data
|
||||
if (!$remaining)
|
||||
{
|
||||
// Percent encode anything invalid or not in iunreserved
|
||||
if (
|
||||
// Invalid sequences
|
||||
!$valid
|
||||
// Non-shortest form sequences are invalid
|
||||
|| $length > 1 && $character <= 0x7F
|
||||
|| $length > 2 && $character <= 0x7FF
|
||||
|| $length > 3 && $character <= 0xFFFF
|
||||
// Outside of range of iunreserved codepoints
|
||||
|| $character < 0x2D
|
||||
|| $character > 0xEFFFD
|
||||
// Noncharacters
|
||||
|| ($character & 0xFFFE) === 0xFFFE
|
||||
|| $character >= 0xFDD0 && $character <= 0xFDEF
|
||||
// Everything else not in iunreserved (this is all BMP)
|
||||
|| $character === 0x2F
|
||||
|| $character > 0x39 && $character < 0x41
|
||||
|| $character > 0x5A && $character < 0x61
|
||||
|| $character > 0x7A && $character < 0x7E
|
||||
|| $character > 0x7E && $character < 0xA0
|
||||
|| $character > 0xD7FF && $character < 0xF900
|
||||
)
|
||||
{
|
||||
for ($j = $start; $j <= $i; $j++)
|
||||
{
|
||||
$string .= '%' . strtoupper($bytes[$j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($j = $start; $j <= $i; $j++)
|
||||
{
|
||||
$string .= chr(hexdec($bytes[$j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have any bytes left over they are invalid (i.e., we are
|
||||
// mid-way through a multi-byte sequence)
|
||||
if ($remaining)
|
||||
{
|
||||
for ($j = $start; $j < $len; $j++)
|
||||
{
|
||||
$string .= '%' . strtoupper($bytes[$j]);
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the object represents a valid IRI
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid()
|
||||
{
|
||||
return array_sum($this->valid) === count($this->valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the scheme. Returns true on success, false on failure (if there are
|
||||
* any invalid characters).
|
||||
*
|
||||
* @access public
|
||||
* @param string $scheme
|
||||
* @return bool
|
||||
*/
|
||||
public function set_scheme($scheme)
|
||||
{
|
||||
if ($scheme === null || $scheme === '')
|
||||
{
|
||||
$this->scheme = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$len = strlen($scheme);
|
||||
switch (true)
|
||||
{
|
||||
case $len > 1:
|
||||
if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
|
||||
{
|
||||
$this->scheme = null;
|
||||
$this->valid[__FUNCTION__] = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
case $len > 0:
|
||||
if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
|
||||
{
|
||||
$this->scheme = null;
|
||||
$this->valid[__FUNCTION__] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->scheme = strtolower($scheme);
|
||||
}
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authority. Returns true on success, false on failure (if there are
|
||||
* any invalid characters).
|
||||
*
|
||||
* @access public
|
||||
* @param string $authority
|
||||
* @return bool
|
||||
*/
|
||||
public function set_authority($authority)
|
||||
{
|
||||
if (($userinfo_end = strrpos($authority, '@')) !== false)
|
||||
{
|
||||
$userinfo = substr($authority, 0, $userinfo_end);
|
||||
$authority = substr($authority, $userinfo_end + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$userinfo = null;
|
||||
}
|
||||
|
||||
if (($port_start = strpos($authority, ':')) !== false)
|
||||
{
|
||||
$port = substr($authority, $port_start + 1);
|
||||
if ($port === false)
|
||||
{
|
||||
$port = null;
|
||||
}
|
||||
$authority = substr($authority, 0, $port_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
$port = null;
|
||||
}
|
||||
|
||||
return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the userinfo.
|
||||
*
|
||||
* @access public
|
||||
* @param string $userinfo
|
||||
* @return bool
|
||||
*/
|
||||
public function set_userinfo($userinfo)
|
||||
{
|
||||
if ($userinfo === null || $userinfo === '')
|
||||
{
|
||||
$this->userinfo = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
|
||||
}
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the host. Returns true on success, false on failure (if there are
|
||||
* any invalid characters).
|
||||
*
|
||||
* @access public
|
||||
* @param string $host
|
||||
* @return bool
|
||||
*/
|
||||
public function set_host($host)
|
||||
{
|
||||
if ($host === null || $host === '')
|
||||
{
|
||||
$this->host = null;
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
elseif ($host[0] === '[' && substr($host, -1) === ']')
|
||||
{
|
||||
if (SimplePie_Net_IPv6::checkIPv6(substr($host, 1, -1)))
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->host = null;
|
||||
$this->valid[__FUNCTION__] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the port. Returns true on success, false on failure (if there are
|
||||
* any invalid characters).
|
||||
*
|
||||
* @access public
|
||||
* @param string $port
|
||||
* @return bool
|
||||
*/
|
||||
public function set_port($port)
|
||||
{
|
||||
if ($port === null || $port === '')
|
||||
{
|
||||
$this->port = null;
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
elseif (strspn($port, '0123456789') === strlen($port))
|
||||
{
|
||||
$this->port = (int) $port;
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->port = null;
|
||||
$this->valid[__FUNCTION__] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path.
|
||||
*
|
||||
* @access public
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
public function set_path($path)
|
||||
{
|
||||
if ($path === null || $path === '')
|
||||
{
|
||||
$this->path = null;
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
|
||||
{
|
||||
$this->path = null;
|
||||
$this->valid[__FUNCTION__] = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
$this->path = $this->remove_dot_segments($this->path);
|
||||
}
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query.
|
||||
*
|
||||
* @access public
|
||||
* @param string $query
|
||||
* @return bool
|
||||
*/
|
||||
public function set_query($query)
|
||||
{
|
||||
if ($query === null || $query === '')
|
||||
{
|
||||
$this->query = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
|
||||
}
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fragment.
|
||||
*
|
||||
* @access public
|
||||
* @param string $fragment
|
||||
* @return bool
|
||||
*/
|
||||
public function set_fragment($fragment)
|
||||
{
|
||||
if ($fragment === null || $fragment === '')
|
||||
{
|
||||
$this->fragment = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
|
||||
}
|
||||
$this->valid[__FUNCTION__] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete IRI
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_iri()
|
||||
{
|
||||
$iri = '';
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
$iri .= $this->scheme . ':';
|
||||
}
|
||||
if (($authority = $this->get_authority()) !== null)
|
||||
{
|
||||
$iri .= '//' . $authority;
|
||||
}
|
||||
if ($this->path !== null)
|
||||
{
|
||||
$iri .= $this->path;
|
||||
}
|
||||
if ($this->query !== null)
|
||||
{
|
||||
$iri .= '?' . $this->query;
|
||||
}
|
||||
if ($this->fragment !== null)
|
||||
{
|
||||
$iri .= '#' . $this->fragment;
|
||||
}
|
||||
|
||||
if ($iri !== '')
|
||||
{
|
||||
return $iri;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scheme
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_scheme()
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete authority
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_authority()
|
||||
{
|
||||
$authority = '';
|
||||
if ($this->userinfo !== null)
|
||||
{
|
||||
$authority .= $this->userinfo . '@';
|
||||
}
|
||||
if ($this->host !== null)
|
||||
{
|
||||
$authority .= $this->host;
|
||||
}
|
||||
if ($this->port !== null)
|
||||
{
|
||||
$authority .= ':' . $this->port;
|
||||
}
|
||||
|
||||
if ($authority !== '')
|
||||
{
|
||||
return $authority;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user information
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_userinfo()
|
||||
{
|
||||
return $this->userinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the host
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_host()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the port
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_port()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_path()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_query()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fragment
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function get_fragment()
|
||||
{
|
||||
return $this->fragment;
|
||||
}
|
||||
}
|
||||
2576
inc/3rdparty/simplepie/SimplePie/Item.php
vendored
2576
inc/3rdparty/simplepie/SimplePie/Item.php
vendored
File diff suppressed because it is too large
Load Diff
314
inc/3rdparty/simplepie/SimplePie/Locator.php
vendored
314
inc/3rdparty/simplepie/SimplePie/Locator.php
vendored
@ -1,314 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Locator
|
||||
{
|
||||
var $useragent;
|
||||
var $timeout;
|
||||
var $file;
|
||||
var $local = array();
|
||||
var $elsewhere = array();
|
||||
var $file_class = 'SimplePie_File';
|
||||
var $cached_entities = array();
|
||||
var $http_base;
|
||||
var $base;
|
||||
var $base_location = 0;
|
||||
var $checked_feeds = 0;
|
||||
var $max_checked_feeds = 10;
|
||||
var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
|
||||
|
||||
public function __construct(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
|
||||
{
|
||||
$this->file =& $file;
|
||||
$this->file_class = $file_class;
|
||||
$this->useragent = $useragent;
|
||||
$this->timeout = $timeout;
|
||||
$this->max_checked_feeds = $max_checked_feeds;
|
||||
$this->content_type_sniffer_class = $content_type_sniffer_class;
|
||||
}
|
||||
|
||||
public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
|
||||
{
|
||||
if ($this->is_feed($this->file))
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
|
||||
{
|
||||
$sniffer = new $this->content_type_sniffer_class($this->file);
|
||||
if ($sniffer->get_type() !== 'text/html')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & ~SIMPLEPIE_LOCATOR_NONE)
|
||||
{
|
||||
$this->get_base();
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
|
||||
{
|
||||
return $working[0];
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
|
||||
{
|
||||
if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function is_feed(&$file)
|
||||
{
|
||||
if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
|
||||
{
|
||||
$sniffer = new $this->content_type_sniffer_class($file);
|
||||
$sniffed = $sniffer->get_type();
|
||||
if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_base()
|
||||
{
|
||||
$this->http_base = $this->file->url;
|
||||
$this->base = $this->http_base;
|
||||
$elements = SimplePie_Misc::get_element('base', $this->file->body);
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
if ($element['attribs']['href']['data'] !== '')
|
||||
{
|
||||
$this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
|
||||
$this->base_location = $element['offset'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function autodiscovery()
|
||||
{
|
||||
$links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
|
||||
$done = array();
|
||||
$feeds = array();
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
|
||||
{
|
||||
$rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
|
||||
|
||||
if ($this->base_location < $link['offset'])
|
||||
{
|
||||
$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
|
||||
}
|
||||
|
||||
if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = new $this->file_class($href, $this->timeout, 5, $headers, $this->useragent);
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
$feeds[$href] = $feed;
|
||||
}
|
||||
}
|
||||
$done[] = $href;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($feeds))
|
||||
{
|
||||
return array_values($feeds);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_links()
|
||||
{
|
||||
$links = SimplePie_Misc::get_element('a', $this->file->body);
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if (isset($link['attribs']['href']['data']))
|
||||
{
|
||||
$href = trim($link['attribs']['href']['data']);
|
||||
$parsed = SimplePie_Misc::parse_url($href);
|
||||
if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
|
||||
{
|
||||
if ($this->base_location < $link['offset'])
|
||||
{
|
||||
$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
$href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
|
||||
}
|
||||
|
||||
$current = SimplePie_Misc::parse_url($this->file->url);
|
||||
|
||||
if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
|
||||
{
|
||||
$this->local[] = $href;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->elsewhere[] = $href;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->local = array_unique($this->local);
|
||||
$this->elsewhere = array_unique($this->elsewhere);
|
||||
if (!empty($this->local) || !empty($this->elsewhere))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function extension(&$array)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = new $this->file_class($value, $this->timeout, 5, $headers, $this->useragent);
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
return $feed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function body(&$array)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (preg_match('/(rss|rdf|atom|xml)/i', $value))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
return $feed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
2366
inc/3rdparty/simplepie/SimplePie/Misc.php
vendored
2366
inc/3rdparty/simplepie/SimplePie/Misc.php
vendored
File diff suppressed because it is too large
Load Diff
258
inc/3rdparty/simplepie/SimplePie/Net/IPv6.php
vendored
258
inc/3rdparty/simplepie/SimplePie/Net/IPv6.php
vendored
@ -1,258 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/package/Net_IPv6
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @author Geoffrey Sneddon <geoffers@gmail.com>
|
||||
*/
|
||||
class SimplePie_Net_IPv6
|
||||
{
|
||||
/**
|
||||
* Removes a possible existing netmask specification of an IP address.
|
||||
*
|
||||
* @param string $ip the (compressed) IP as Hex representation
|
||||
* @return string the IP the without netmask
|
||||
* @since 1.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function removeNetmaskSpec($ip)
|
||||
{
|
||||
if (strpos($ip, '/') !== false)
|
||||
{
|
||||
list($addr, $nm) = explode('/', $ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
$addr = $ip;
|
||||
}
|
||||
return $addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uncompresses an IPv6 address
|
||||
*
|
||||
* RFC 2373 allows you to compress zeros in an address to '::'. This
|
||||
* function expects an valid IPv6 address and expands the '::' to
|
||||
* the required zeros.
|
||||
*
|
||||
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
|
||||
* ::1 -> 0:0:0:0:0:0:0:1
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $ip a valid IPv6-address (hex format)
|
||||
* @return string the uncompressed IPv6-address (hex format)
|
||||
*/
|
||||
public static function Uncompress($ip)
|
||||
{
|
||||
$uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
|
||||
$c1 = -1;
|
||||
$c2 = -1;
|
||||
if (strpos($ip, '::') !== false)
|
||||
{
|
||||
list($ip1, $ip2) = explode('::', $ip);
|
||||
if ($ip1 === '')
|
||||
{
|
||||
$c1 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$pos = 0;
|
||||
if (($pos = substr_count($ip1, ':')) > 0)
|
||||
{
|
||||
$c1 = $pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c1 = 0;
|
||||
}
|
||||
}
|
||||
if ($ip2 === '')
|
||||
{
|
||||
$c2 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$pos = 0;
|
||||
if (($pos = substr_count($ip2, ':')) > 0)
|
||||
{
|
||||
$c2 = $pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c2 = 0;
|
||||
}
|
||||
}
|
||||
if (strstr($ip2, '.'))
|
||||
{
|
||||
$c2++;
|
||||
}
|
||||
// ::
|
||||
if ($c1 === -1 && $c2 === -1)
|
||||
{
|
||||
$uip = '0:0:0:0:0:0:0:0';
|
||||
}
|
||||
// ::xxx
|
||||
else if ($c1 === -1)
|
||||
{
|
||||
$fill = str_repeat('0:', 7 - $c2);
|
||||
$uip = str_replace('::', $fill, $uip);
|
||||
}
|
||||
// xxx::
|
||||
else if ($c2 === -1)
|
||||
{
|
||||
$fill = str_repeat(':0', 7 - $c1);
|
||||
$uip = str_replace('::', $fill, $uip);
|
||||
}
|
||||
// xxx::xxx
|
||||
else
|
||||
{
|
||||
$fill = str_repeat(':0:', 6 - $c2 - $c1);
|
||||
$uip = str_replace('::', $fill, $uip);
|
||||
$uip = str_replace('::', ':', $uip);
|
||||
}
|
||||
}
|
||||
return $uip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an IPv6 address into the IPv6 and a possible IPv4 part
|
||||
*
|
||||
* RFC 2373 allows you to note the last two parts of an IPv6 address as
|
||||
* an IPv4 compatible address
|
||||
*
|
||||
* Example: 0:0:0:0:0:0:13.1.68.3
|
||||
* 0:0:0:0:0:FFFF:129.144.52.38
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $ip a valid IPv6-address (hex format)
|
||||
* @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
|
||||
*/
|
||||
public static function SplitV64($ip)
|
||||
{
|
||||
$ip = SimplePie_Net_IPv6::Uncompress($ip);
|
||||
if (strstr($ip, '.'))
|
||||
{
|
||||
$pos = strrpos($ip, ':');
|
||||
$ip[$pos] = '_';
|
||||
$ipPart = explode('_', $ip);
|
||||
return $ipPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($ip, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an IPv6 address
|
||||
*
|
||||
* Checks if the given IP is IPv6-compatible
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $ip a valid IPv6-address
|
||||
* @return bool true if $ip is an IPv6 address
|
||||
*/
|
||||
public static function checkIPv6($ip)
|
||||
{
|
||||
$ipPart = SimplePie_Net_IPv6::SplitV64($ip);
|
||||
$count = 0;
|
||||
if (!empty($ipPart[0]))
|
||||
{
|
||||
$ipv6 = explode(':', $ipPart[0]);
|
||||
for ($i = 0; $i < count($ipv6); $i++)
|
||||
{
|
||||
$dec = hexdec($ipv6[$i]);
|
||||
$hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
|
||||
if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
|
||||
{
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count === 8)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
elseif ($count === 6 && !empty($ipPart[1]))
|
||||
{
|
||||
$ipv4 = explode('.', $ipPart[1]);
|
||||
$count = 0;
|
||||
foreach ($ipv4 as $ipv4_part)
|
||||
{
|
||||
if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
|
||||
{
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count === 4)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
983
inc/3rdparty/simplepie/SimplePie/Parse/Date.php
vendored
983
inc/3rdparty/simplepie/SimplePie/Parse/Date.php
vendored
@ -1,983 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Date Parser
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Parse_Date
|
||||
{
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $date;
|
||||
|
||||
/**
|
||||
* List of days, calendar day name => ordinal day number in the week
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $day = array(
|
||||
// English
|
||||
'mon' => 1,
|
||||
'monday' => 1,
|
||||
'tue' => 2,
|
||||
'tuesday' => 2,
|
||||
'wed' => 3,
|
||||
'wednesday' => 3,
|
||||
'thu' => 4,
|
||||
'thursday' => 4,
|
||||
'fri' => 5,
|
||||
'friday' => 5,
|
||||
'sat' => 6,
|
||||
'saturday' => 6,
|
||||
'sun' => 7,
|
||||
'sunday' => 7,
|
||||
// Dutch
|
||||
'maandag' => 1,
|
||||
'dinsdag' => 2,
|
||||
'woensdag' => 3,
|
||||
'donderdag' => 4,
|
||||
'vrijdag' => 5,
|
||||
'zaterdag' => 6,
|
||||
'zondag' => 7,
|
||||
// French
|
||||
'lundi' => 1,
|
||||
'mardi' => 2,
|
||||
'mercredi' => 3,
|
||||
'jeudi' => 4,
|
||||
'vendredi' => 5,
|
||||
'samedi' => 6,
|
||||
'dimanche' => 7,
|
||||
// German
|
||||
'montag' => 1,
|
||||
'dienstag' => 2,
|
||||
'mittwoch' => 3,
|
||||
'donnerstag' => 4,
|
||||
'freitag' => 5,
|
||||
'samstag' => 6,
|
||||
'sonnabend' => 6,
|
||||
'sonntag' => 7,
|
||||
// Italian
|
||||
'lunedì' => 1,
|
||||
'martedì' => 2,
|
||||
'mercoledì' => 3,
|
||||
'giovedì' => 4,
|
||||
'venerdì' => 5,
|
||||
'sabato' => 6,
|
||||
'domenica' => 7,
|
||||
// Spanish
|
||||
'lunes' => 1,
|
||||
'martes' => 2,
|
||||
'miércoles' => 3,
|
||||
'jueves' => 4,
|
||||
'viernes' => 5,
|
||||
'sábado' => 6,
|
||||
'domingo' => 7,
|
||||
// Finnish
|
||||
'maanantai' => 1,
|
||||
'tiistai' => 2,
|
||||
'keskiviikko' => 3,
|
||||
'torstai' => 4,
|
||||
'perjantai' => 5,
|
||||
'lauantai' => 6,
|
||||
'sunnuntai' => 7,
|
||||
// Hungarian
|
||||
'hétfő' => 1,
|
||||
'kedd' => 2,
|
||||
'szerda' => 3,
|
||||
'csütörtok' => 4,
|
||||
'péntek' => 5,
|
||||
'szombat' => 6,
|
||||
'vasárnap' => 7,
|
||||
// Greek
|
||||
'Δευ' => 1,
|
||||
'Τρι' => 2,
|
||||
'Τετ' => 3,
|
||||
'Πεμ' => 4,
|
||||
'Παρ' => 5,
|
||||
'Σαβ' => 6,
|
||||
'Κυρ' => 7,
|
||||
);
|
||||
|
||||
/**
|
||||
* List of months, calendar month name => calendar month number
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $month = array(
|
||||
// English
|
||||
'jan' => 1,
|
||||
'january' => 1,
|
||||
'feb' => 2,
|
||||
'february' => 2,
|
||||
'mar' => 3,
|
||||
'march' => 3,
|
||||
'apr' => 4,
|
||||
'april' => 4,
|
||||
'may' => 5,
|
||||
// No long form of May
|
||||
'jun' => 6,
|
||||
'june' => 6,
|
||||
'jul' => 7,
|
||||
'july' => 7,
|
||||
'aug' => 8,
|
||||
'august' => 8,
|
||||
'sep' => 9,
|
||||
'september' => 8,
|
||||
'oct' => 10,
|
||||
'october' => 10,
|
||||
'nov' => 11,
|
||||
'november' => 11,
|
||||
'dec' => 12,
|
||||
'december' => 12,
|
||||
// Dutch
|
||||
'januari' => 1,
|
||||
'februari' => 2,
|
||||
'maart' => 3,
|
||||
'april' => 4,
|
||||
'mei' => 5,
|
||||
'juni' => 6,
|
||||
'juli' => 7,
|
||||
'augustus' => 8,
|
||||
'september' => 9,
|
||||
'oktober' => 10,
|
||||
'november' => 11,
|
||||
'december' => 12,
|
||||
// French
|
||||
'janvier' => 1,
|
||||
'février' => 2,
|
||||
'mars' => 3,
|
||||
'avril' => 4,
|
||||
'mai' => 5,
|
||||
'juin' => 6,
|
||||
'juillet' => 7,
|
||||
'août' => 8,
|
||||
'septembre' => 9,
|
||||
'octobre' => 10,
|
||||
'novembre' => 11,
|
||||
'décembre' => 12,
|
||||
// German
|
||||
'januar' => 1,
|
||||
'februar' => 2,
|
||||
'märz' => 3,
|
||||
'april' => 4,
|
||||
'mai' => 5,
|
||||
'juni' => 6,
|
||||
'juli' => 7,
|
||||
'august' => 8,
|
||||
'september' => 9,
|
||||
'oktober' => 10,
|
||||
'november' => 11,
|
||||
'dezember' => 12,
|
||||
// Italian
|
||||
'gennaio' => 1,
|
||||
'febbraio' => 2,
|
||||
'marzo' => 3,
|
||||
'aprile' => 4,
|
||||
'maggio' => 5,
|
||||
'giugno' => 6,
|
||||
'luglio' => 7,
|
||||
'agosto' => 8,
|
||||
'settembre' => 9,
|
||||
'ottobre' => 10,
|
||||
'novembre' => 11,
|
||||
'dicembre' => 12,
|
||||
// Spanish
|
||||
'enero' => 1,
|
||||
'febrero' => 2,
|
||||
'marzo' => 3,
|
||||
'abril' => 4,
|
||||
'mayo' => 5,
|
||||
'junio' => 6,
|
||||
'julio' => 7,
|
||||
'agosto' => 8,
|
||||
'septiembre' => 9,
|
||||
'setiembre' => 9,
|
||||
'octubre' => 10,
|
||||
'noviembre' => 11,
|
||||
'diciembre' => 12,
|
||||
// Finnish
|
||||
'tammikuu' => 1,
|
||||
'helmikuu' => 2,
|
||||
'maaliskuu' => 3,
|
||||
'huhtikuu' => 4,
|
||||
'toukokuu' => 5,
|
||||
'kesäkuu' => 6,
|
||||
'heinäkuu' => 7,
|
||||
'elokuu' => 8,
|
||||
'suuskuu' => 9,
|
||||
'lokakuu' => 10,
|
||||
'marras' => 11,
|
||||
'joulukuu' => 12,
|
||||
// Hungarian
|
||||
'január' => 1,
|
||||
'február' => 2,
|
||||
'március' => 3,
|
||||
'április' => 4,
|
||||
'május' => 5,
|
||||
'június' => 6,
|
||||
'július' => 7,
|
||||
'augusztus' => 8,
|
||||
'szeptember' => 9,
|
||||
'október' => 10,
|
||||
'november' => 11,
|
||||
'december' => 12,
|
||||
// Greek
|
||||
'Ιαν' => 1,
|
||||
'Φεβ' => 2,
|
||||
'Μάώ' => 3,
|
||||
'Μαώ' => 3,
|
||||
'Απρ' => 4,
|
||||
'Μάι' => 5,
|
||||
'Μαϊ' => 5,
|
||||
'Μαι' => 5,
|
||||
'Ιούν' => 6,
|
||||
'Ιον' => 6,
|
||||
'Ιούλ' => 7,
|
||||
'Ιολ' => 7,
|
||||
'Αύγ' => 8,
|
||||
'Αυγ' => 8,
|
||||
'Σεπ' => 9,
|
||||
'Οκτ' => 10,
|
||||
'Νοέ' => 11,
|
||||
'Δεκ' => 12,
|
||||
);
|
||||
|
||||
/**
|
||||
* List of timezones, abbreviation => offset from UTC
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $timezone = array(
|
||||
'ACDT' => 37800,
|
||||
'ACIT' => 28800,
|
||||
'ACST' => 34200,
|
||||
'ACT' => -18000,
|
||||
'ACWDT' => 35100,
|
||||
'ACWST' => 31500,
|
||||
'AEDT' => 39600,
|
||||
'AEST' => 36000,
|
||||
'AFT' => 16200,
|
||||
'AKDT' => -28800,
|
||||
'AKST' => -32400,
|
||||
'AMDT' => 18000,
|
||||
'AMT' => -14400,
|
||||
'ANAST' => 46800,
|
||||
'ANAT' => 43200,
|
||||
'ART' => -10800,
|
||||
'AZOST' => -3600,
|
||||
'AZST' => 18000,
|
||||
'AZT' => 14400,
|
||||
'BIOT' => 21600,
|
||||
'BIT' => -43200,
|
||||
'BOT' => -14400,
|
||||
'BRST' => -7200,
|
||||
'BRT' => -10800,
|
||||
'BST' => 3600,
|
||||
'BTT' => 21600,
|
||||
'CAST' => 18000,
|
||||
'CAT' => 7200,
|
||||
'CCT' => 23400,
|
||||
'CDT' => -18000,
|
||||
'CEDT' => 7200,
|
||||
'CET' => 3600,
|
||||
'CGST' => -7200,
|
||||
'CGT' => -10800,
|
||||
'CHADT' => 49500,
|
||||
'CHAST' => 45900,
|
||||
'CIST' => -28800,
|
||||
'CKT' => -36000,
|
||||
'CLDT' => -10800,
|
||||
'CLST' => -14400,
|
||||
'COT' => -18000,
|
||||
'CST' => -21600,
|
||||
'CVT' => -3600,
|
||||
'CXT' => 25200,
|
||||
'DAVT' => 25200,
|
||||
'DTAT' => 36000,
|
||||
'EADT' => -18000,
|
||||
'EAST' => -21600,
|
||||
'EAT' => 10800,
|
||||
'ECT' => -18000,
|
||||
'EDT' => -14400,
|
||||
'EEST' => 10800,
|
||||
'EET' => 7200,
|
||||
'EGT' => -3600,
|
||||
'EKST' => 21600,
|
||||
'EST' => -18000,
|
||||
'FJT' => 43200,
|
||||
'FKDT' => -10800,
|
||||
'FKST' => -14400,
|
||||
'FNT' => -7200,
|
||||
'GALT' => -21600,
|
||||
'GEDT' => 14400,
|
||||
'GEST' => 10800,
|
||||
'GFT' => -10800,
|
||||
'GILT' => 43200,
|
||||
'GIT' => -32400,
|
||||
'GST' => 14400,
|
||||
'GST' => -7200,
|
||||
'GYT' => -14400,
|
||||
'HAA' => -10800,
|
||||
'HAC' => -18000,
|
||||
'HADT' => -32400,
|
||||
'HAE' => -14400,
|
||||
'HAP' => -25200,
|
||||
'HAR' => -21600,
|
||||
'HAST' => -36000,
|
||||
'HAT' => -9000,
|
||||
'HAY' => -28800,
|
||||
'HKST' => 28800,
|
||||
'HMT' => 18000,
|
||||
'HNA' => -14400,
|
||||
'HNC' => -21600,
|
||||
'HNE' => -18000,
|
||||
'HNP' => -28800,
|
||||
'HNR' => -25200,
|
||||
'HNT' => -12600,
|
||||
'HNY' => -32400,
|
||||
'IRDT' => 16200,
|
||||
'IRKST' => 32400,
|
||||
'IRKT' => 28800,
|
||||
'IRST' => 12600,
|
||||
'JFDT' => -10800,
|
||||
'JFST' => -14400,
|
||||
'JST' => 32400,
|
||||
'KGST' => 21600,
|
||||
'KGT' => 18000,
|
||||
'KOST' => 39600,
|
||||
'KOVST' => 28800,
|
||||
'KOVT' => 25200,
|
||||
'KRAST' => 28800,
|
||||
'KRAT' => 25200,
|
||||
'KST' => 32400,
|
||||
'LHDT' => 39600,
|
||||
'LHST' => 37800,
|
||||
'LINT' => 50400,
|
||||
'LKT' => 21600,
|
||||
'MAGST' => 43200,
|
||||
'MAGT' => 39600,
|
||||
'MAWT' => 21600,
|
||||
'MDT' => -21600,
|
||||
'MESZ' => 7200,
|
||||
'MEZ' => 3600,
|
||||
'MHT' => 43200,
|
||||
'MIT' => -34200,
|
||||
'MNST' => 32400,
|
||||
'MSDT' => 14400,
|
||||
'MSST' => 10800,
|
||||
'MST' => -25200,
|
||||
'MUT' => 14400,
|
||||
'MVT' => 18000,
|
||||
'MYT' => 28800,
|
||||
'NCT' => 39600,
|
||||
'NDT' => -9000,
|
||||
'NFT' => 41400,
|
||||
'NMIT' => 36000,
|
||||
'NOVST' => 25200,
|
||||
'NOVT' => 21600,
|
||||
'NPT' => 20700,
|
||||
'NRT' => 43200,
|
||||
'NST' => -12600,
|
||||
'NUT' => -39600,
|
||||
'NZDT' => 46800,
|
||||
'NZST' => 43200,
|
||||
'OMSST' => 25200,
|
||||
'OMST' => 21600,
|
||||
'PDT' => -25200,
|
||||
'PET' => -18000,
|
||||
'PETST' => 46800,
|
||||
'PETT' => 43200,
|
||||
'PGT' => 36000,
|
||||
'PHOT' => 46800,
|
||||
'PHT' => 28800,
|
||||
'PKT' => 18000,
|
||||
'PMDT' => -7200,
|
||||
'PMST' => -10800,
|
||||
'PONT' => 39600,
|
||||
'PST' => -28800,
|
||||
'PWT' => 32400,
|
||||
'PYST' => -10800,
|
||||
'PYT' => -14400,
|
||||
'RET' => 14400,
|
||||
'ROTT' => -10800,
|
||||
'SAMST' => 18000,
|
||||
'SAMT' => 14400,
|
||||
'SAST' => 7200,
|
||||
'SBT' => 39600,
|
||||
'SCDT' => 46800,
|
||||
'SCST' => 43200,
|
||||
'SCT' => 14400,
|
||||
'SEST' => 3600,
|
||||
'SGT' => 28800,
|
||||
'SIT' => 28800,
|
||||
'SRT' => -10800,
|
||||
'SST' => -39600,
|
||||
'SYST' => 10800,
|
||||
'SYT' => 7200,
|
||||
'TFT' => 18000,
|
||||
'THAT' => -36000,
|
||||
'TJT' => 18000,
|
||||
'TKT' => -36000,
|
||||
'TMT' => 18000,
|
||||
'TOT' => 46800,
|
||||
'TPT' => 32400,
|
||||
'TRUT' => 36000,
|
||||
'TVT' => 43200,
|
||||
'TWT' => 28800,
|
||||
'UYST' => -7200,
|
||||
'UYT' => -10800,
|
||||
'UZT' => 18000,
|
||||
'VET' => -14400,
|
||||
'VLAST' => 39600,
|
||||
'VLAT' => 36000,
|
||||
'VOST' => 21600,
|
||||
'VUT' => 39600,
|
||||
'WAST' => 7200,
|
||||
'WAT' => 3600,
|
||||
'WDT' => 32400,
|
||||
'WEST' => 3600,
|
||||
'WFT' => 43200,
|
||||
'WIB' => 25200,
|
||||
'WIT' => 32400,
|
||||
'WITA' => 28800,
|
||||
'WKST' => 18000,
|
||||
'WST' => 28800,
|
||||
'YAKST' => 36000,
|
||||
'YAKT' => 32400,
|
||||
'YAPT' => 36000,
|
||||
'YEKST' => 21600,
|
||||
'YEKT' => 18000,
|
||||
);
|
||||
|
||||
/**
|
||||
* Cached PCRE for SimplePie_Parse_Date::$day
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $day_pcre;
|
||||
|
||||
/**
|
||||
* Cached PCRE for SimplePie_Parse_Date::$month
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $month_pcre;
|
||||
|
||||
/**
|
||||
* Array of user-added callback methods
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $built_in = array();
|
||||
|
||||
/**
|
||||
* Array of user-added callback methods
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $user = array();
|
||||
|
||||
/**
|
||||
* Create new SimplePie_Parse_Date object, and set self::day_pcre,
|
||||
* self::month_pcre, and self::built_in
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
|
||||
$this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
|
||||
|
||||
static $cache;
|
||||
if (!isset($cache[get_class($this)]))
|
||||
{
|
||||
$all_methods = get_class_methods($this);
|
||||
|
||||
foreach ($all_methods as $method)
|
||||
{
|
||||
if (strtolower(substr($method, 0, 5)) === 'date_')
|
||||
{
|
||||
$cache[get_class($this)][] = $method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($cache[get_class($this)] as $method)
|
||||
{
|
||||
$this->built_in[] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public static function get()
|
||||
{
|
||||
static $object;
|
||||
if (!$object)
|
||||
{
|
||||
$object = new SimplePie_Parse_Date;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a date
|
||||
*
|
||||
* @final
|
||||
* @access public
|
||||
* @param string $date Date to parse
|
||||
* @return int Timestamp corresponding to date string, or false on failure
|
||||
*/
|
||||
public function parse($date)
|
||||
{
|
||||
foreach ($this->user as $method)
|
||||
{
|
||||
if (($returned = call_user_func($method, $date)) !== false)
|
||||
{
|
||||
return $returned;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->built_in as $method)
|
||||
{
|
||||
if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
|
||||
{
|
||||
return $returned;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback method to parse a date
|
||||
*
|
||||
* @final
|
||||
* @access public
|
||||
* @param callback $callback
|
||||
*/
|
||||
public function add_callback($callback)
|
||||
{
|
||||
if (is_callable($callback))
|
||||
{
|
||||
$this->user[] = $callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
|
||||
* well as allowing any of upper or lower case "T", horizontal tabs, or
|
||||
* spaces to be used as the time seperator (including more than one))
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_w3cdtf($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$year = '([0-9]{4})';
|
||||
$month = $day = $hour = $minute = $second = '([0-9]{2})';
|
||||
$decimal = '([0-9]*)';
|
||||
$zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
|
||||
$pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Year
|
||||
2: Month
|
||||
3: Day
|
||||
4: Hour
|
||||
5: Minute
|
||||
6: Second
|
||||
7: Decimal fraction of a second
|
||||
8: Zulu
|
||||
9: Timezone ±
|
||||
10: Timezone hours
|
||||
11: Timezone minutes
|
||||
*/
|
||||
|
||||
// Fill in empty matches
|
||||
for ($i = count($match); $i <= 3; $i++)
|
||||
{
|
||||
$match[$i] = '1';
|
||||
}
|
||||
|
||||
for ($i = count($match); $i <= 7; $i++)
|
||||
{
|
||||
$match[$i] = '0';
|
||||
}
|
||||
|
||||
// Numeric timezone
|
||||
if (isset($match[9]) && $match[9] !== '')
|
||||
{
|
||||
$timezone = $match[10] * 3600;
|
||||
$timezone += $match[11] * 60;
|
||||
if ($match[9] === '-')
|
||||
{
|
||||
$timezone = 0 - $timezone;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Convert the number of seconds to an integer, taking decimals into account
|
||||
$second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
|
||||
|
||||
return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove RFC822 comments
|
||||
*
|
||||
* @access protected
|
||||
* @param string $data Data to strip comments from
|
||||
* @return string Comment stripped string
|
||||
*/
|
||||
public function remove_rfc2822_comments($string)
|
||||
{
|
||||
$string = (string) $string;
|
||||
$position = 0;
|
||||
$length = strlen($string);
|
||||
$depth = 0;
|
||||
|
||||
$output = '';
|
||||
|
||||
while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
|
||||
{
|
||||
$output .= substr($string, $position, $pos - $position);
|
||||
$position = $pos + 1;
|
||||
if ($string[$pos - 1] !== '\\')
|
||||
{
|
||||
$depth++;
|
||||
while ($depth && $position < $length)
|
||||
{
|
||||
$position += strcspn($string, '()', $position);
|
||||
if ($string[$position - 1] === '\\')
|
||||
{
|
||||
$position++;
|
||||
continue;
|
||||
}
|
||||
elseif (isset($string[$position]))
|
||||
{
|
||||
switch ($string[$position])
|
||||
{
|
||||
case '(':
|
||||
$depth++;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
$depth--;
|
||||
break;
|
||||
}
|
||||
$position++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= '(';
|
||||
}
|
||||
}
|
||||
$output .= substr($string, $position);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RFC2822's date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_rfc2822($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$wsp = '[\x09\x20]';
|
||||
$fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
|
||||
$optional_fws = $fws . '?';
|
||||
$day_name = $this->day_pcre;
|
||||
$month = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$hour = $minute = $second = '([0-9]{2})';
|
||||
$year = '([0-9]{2,4})';
|
||||
$num_zone = '([+\-])([0-9]{2})([0-9]{2})';
|
||||
$character_zone = '([A-Z]{1,5})';
|
||||
$zone = '(?:' . $num_zone . '|' . $character_zone . ')';
|
||||
$pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
|
||||
}
|
||||
if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Day
|
||||
3: Month
|
||||
4: Year
|
||||
5: Hour
|
||||
6: Minute
|
||||
7: Second
|
||||
8: Timezone ±
|
||||
9: Timezone hours
|
||||
10: Timezone minutes
|
||||
11: Alphabetic timezone
|
||||
*/
|
||||
|
||||
// Find the month number
|
||||
$month = $this->month[strtolower($match[3])];
|
||||
|
||||
// Numeric timezone
|
||||
if ($match[8] !== '')
|
||||
{
|
||||
$timezone = $match[9] * 3600;
|
||||
$timezone += $match[10] * 60;
|
||||
if ($match[8] === '-')
|
||||
{
|
||||
$timezone = 0 - $timezone;
|
||||
}
|
||||
}
|
||||
// Character timezone
|
||||
elseif (isset($this->timezone[strtoupper($match[11])]))
|
||||
{
|
||||
$timezone = $this->timezone[strtoupper($match[11])];
|
||||
}
|
||||
// Assume everything else to be -0000
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Deal with 2/3 digit years
|
||||
if ($match[4] < 50)
|
||||
{
|
||||
$match[4] += 2000;
|
||||
}
|
||||
elseif ($match[4] < 1000)
|
||||
{
|
||||
$match[4] += 1900;
|
||||
}
|
||||
|
||||
// Second is optional, if it is empty set it to zero
|
||||
if ($match[7] !== '')
|
||||
{
|
||||
$second = $match[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
$second = 0;
|
||||
}
|
||||
|
||||
return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RFC850's date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_rfc850($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$space = '[\x09\x20]+';
|
||||
$day_name = $this->day_pcre;
|
||||
$month = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$year = $hour = $minute = $second = '([0-9]{2})';
|
||||
$zone = '([A-Z]{1,5})';
|
||||
$pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Day
|
||||
3: Month
|
||||
4: Year
|
||||
5: Hour
|
||||
6: Minute
|
||||
7: Second
|
||||
8: Timezone
|
||||
*/
|
||||
|
||||
// Month
|
||||
$month = $this->month[strtolower($match[3])];
|
||||
|
||||
// Character timezone
|
||||
if (isset($this->timezone[strtoupper($match[8])]))
|
||||
{
|
||||
$timezone = $this->timezone[strtoupper($match[8])];
|
||||
}
|
||||
// Assume everything else to be -0000
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Deal with 2 digit year
|
||||
if ($match[4] < 50)
|
||||
{
|
||||
$match[4] += 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
$match[4] += 1900;
|
||||
}
|
||||
|
||||
return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse C99's asctime()'s date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_asctime($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$space = '[\x09\x20]+';
|
||||
$wday_name = $this->day_pcre;
|
||||
$mon_name = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$hour = $sec = $min = '([0-9]{2})';
|
||||
$year = '([0-9]{4})';
|
||||
$terminator = '\x0A?\x00?';
|
||||
$pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Month
|
||||
3: Day
|
||||
4: Hour
|
||||
5: Minute
|
||||
6: Second
|
||||
7: Year
|
||||
*/
|
||||
|
||||
$month = $this->month[strtolower($match[2])];
|
||||
return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse dates using strtotime()
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_strtotime($date)
|
||||
{
|
||||
$strtotime = strtotime($date);
|
||||
if ($strtotime === -1 || $strtotime === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $strtotime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
387
inc/3rdparty/simplepie/SimplePie/Parser.php
vendored
387
inc/3rdparty/simplepie/SimplePie/Parser.php
vendored
@ -1,387 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Parser
|
||||
{
|
||||
var $error_code;
|
||||
var $error_string;
|
||||
var $current_line;
|
||||
var $current_column;
|
||||
var $current_byte;
|
||||
var $separator = ' ';
|
||||
var $namespace = array('');
|
||||
var $element = array('');
|
||||
var $xml_base = array('');
|
||||
var $xml_base_explicit = array(false);
|
||||
var $xml_lang = array('');
|
||||
var $data = array();
|
||||
var $datas = array(array());
|
||||
var $current_xhtml_construct = -1;
|
||||
var $encoding;
|
||||
|
||||
public function parse(&$data, $encoding)
|
||||
{
|
||||
// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
|
||||
if (strtoupper($encoding) === 'US-ASCII')
|
||||
{
|
||||
$this->encoding = 'UTF-8';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
}
|
||||
|
||||
// Strip BOM:
|
||||
// UTF-32 Big Endian BOM
|
||||
if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
|
||||
{
|
||||
$data = substr($data, 4);
|
||||
}
|
||||
// UTF-32 Little Endian BOM
|
||||
elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
|
||||
{
|
||||
$data = substr($data, 4);
|
||||
}
|
||||
// UTF-16 Big Endian BOM
|
||||
elseif (substr($data, 0, 2) === "\xFE\xFF")
|
||||
{
|
||||
$data = substr($data, 2);
|
||||
}
|
||||
// UTF-16 Little Endian BOM
|
||||
elseif (substr($data, 0, 2) === "\xFF\xFE")
|
||||
{
|
||||
$data = substr($data, 2);
|
||||
}
|
||||
// UTF-8 BOM
|
||||
elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
|
||||
{
|
||||
$data = substr($data, 3);
|
||||
}
|
||||
|
||||
if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
|
||||
{
|
||||
$declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
|
||||
if ($declaration->parse())
|
||||
{
|
||||
$data = substr($data, $pos + 2);
|
||||
$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_string = 'SimplePie bug! Please report this!';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$return = true;
|
||||
|
||||
static $xml_is_sane = null;
|
||||
if ($xml_is_sane === null)
|
||||
{
|
||||
$parser_check = xml_parser_create();
|
||||
xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
|
||||
xml_parser_free($parser_check);
|
||||
$xml_is_sane = isset($values[0]['value']);
|
||||
}
|
||||
|
||||
// Create the parser
|
||||
if ($xml_is_sane)
|
||||
{
|
||||
$xml = xml_parser_create_ns($this->encoding, $this->separator);
|
||||
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
|
||||
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
|
||||
xml_set_object($xml, $this);
|
||||
xml_set_character_data_handler($xml, 'cdata');
|
||||
xml_set_element_handler($xml, 'tag_open', 'tag_close');
|
||||
|
||||
// Parse!
|
||||
if (!xml_parse($xml, $data, true))
|
||||
{
|
||||
$this->error_code = xml_get_error_code($xml);
|
||||
$this->error_string = xml_error_string($this->error_code);
|
||||
$return = false;
|
||||
}
|
||||
$this->current_line = xml_get_current_line_number($xml);
|
||||
$this->current_column = xml_get_current_column_number($xml);
|
||||
$this->current_byte = xml_get_current_byte_index($xml);
|
||||
xml_parser_free($xml);
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
libxml_clear_errors();
|
||||
$xml = new XMLReader();
|
||||
$xml->xml($data);
|
||||
while (@$xml->read())
|
||||
{
|
||||
switch ($xml->nodeType)
|
||||
{
|
||||
|
||||
case constant('XMLReader::END_ELEMENT'):
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tagName = $xml->localName;
|
||||
}
|
||||
$this->tag_close(null, $tagName);
|
||||
break;
|
||||
case constant('XMLReader::ELEMENT'):
|
||||
$empty = $xml->isEmptyElement;
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tagName = $xml->localName;
|
||||
}
|
||||
$attributes = array();
|
||||
while ($xml->moveToNextAttribute())
|
||||
{
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$attrName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$attrName = $xml->localName;
|
||||
}
|
||||
$attributes[$attrName] = $xml->value;
|
||||
}
|
||||
$this->tag_open(null, $tagName, $attributes);
|
||||
if ($empty)
|
||||
{
|
||||
$this->tag_close(null, $tagName);
|
||||
}
|
||||
break;
|
||||
case constant('XMLReader::TEXT'):
|
||||
|
||||
case constant('XMLReader::CDATA'):
|
||||
$this->cdata(null, $xml->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($error = libxml_get_last_error())
|
||||
{
|
||||
$this->error_code = $error->code;
|
||||
$this->error_string = $error->message;
|
||||
$this->current_line = $error->line;
|
||||
$this->current_column = $error->column;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_error_code()
|
||||
{
|
||||
return $this->error_code;
|
||||
}
|
||||
|
||||
public function get_error_string()
|
||||
{
|
||||
return $this->error_string;
|
||||
}
|
||||
|
||||
public function get_current_line()
|
||||
{
|
||||
return $this->current_line;
|
||||
}
|
||||
|
||||
public function get_current_column()
|
||||
{
|
||||
return $this->current_column;
|
||||
}
|
||||
|
||||
public function get_current_byte()
|
||||
{
|
||||
return $this->current_byte;
|
||||
}
|
||||
|
||||
public function get_data()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function tag_open($parser, $tag, $attributes)
|
||||
{
|
||||
list($this->namespace[], $this->element[]) = $this->split_ns($tag);
|
||||
|
||||
$attribs = array();
|
||||
foreach ($attributes as $name => $value)
|
||||
{
|
||||
list($attrib_namespace, $attribute) = $this->split_ns($name);
|
||||
$attribs[$attrib_namespace][$attribute] = $value;
|
||||
}
|
||||
|
||||
if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
|
||||
{
|
||||
$this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
|
||||
$this->xml_base_explicit[] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->xml_base[] = end($this->xml_base);
|
||||
$this->xml_base_explicit[] = end($this->xml_base_explicit);
|
||||
}
|
||||
|
||||
if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
|
||||
{
|
||||
$this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->xml_lang[] = end($this->xml_lang);
|
||||
}
|
||||
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->current_xhtml_construct++;
|
||||
if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
|
||||
{
|
||||
$this->data['data'] .= '<' . end($this->element);
|
||||
if (isset($attribs['']))
|
||||
{
|
||||
foreach ($attribs[''] as $name => $value)
|
||||
{
|
||||
$this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
|
||||
}
|
||||
}
|
||||
$this->data['data'] .= '>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->datas[] =& $this->data;
|
||||
$this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
|
||||
$this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
|
||||
if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
|
||||
|| (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml'))
|
||||
{
|
||||
$this->current_xhtml_construct = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function cdata($parser, $cdata)
|
||||
{
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->data['data'] .= $cdata;
|
||||
}
|
||||
}
|
||||
|
||||
public function tag_close($parser, $tag)
|
||||
{
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->current_xhtml_construct--;
|
||||
if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
|
||||
{
|
||||
$this->data['data'] .= '</' . end($this->element) . '>';
|
||||
}
|
||||
}
|
||||
if ($this->current_xhtml_construct === -1)
|
||||
{
|
||||
$this->data =& $this->datas[count($this->datas) - 1];
|
||||
array_pop($this->datas);
|
||||
}
|
||||
|
||||
array_pop($this->element);
|
||||
array_pop($this->namespace);
|
||||
array_pop($this->xml_base);
|
||||
array_pop($this->xml_base_explicit);
|
||||
array_pop($this->xml_lang);
|
||||
}
|
||||
|
||||
public function split_ns($string)
|
||||
{
|
||||
static $cache = array();
|
||||
if (!isset($cache[$string]))
|
||||
{
|
||||
if ($pos = strpos($string, $this->separator))
|
||||
{
|
||||
static $separator_length;
|
||||
if (!$separator_length)
|
||||
{
|
||||
$separator_length = strlen($this->separator);
|
||||
}
|
||||
$namespace = substr($string, 0, $pos);
|
||||
$local_name = substr($string, $pos + $separator_length);
|
||||
if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
|
||||
{
|
||||
$namespace = SIMPLEPIE_NAMESPACE_ITUNES;
|
||||
}
|
||||
|
||||
// Normalize the Media RSS namespaces
|
||||
if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
|
||||
{
|
||||
$namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
|
||||
}
|
||||
$cache[$string] = array($namespace, $local_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cache[$string] = array('', $string);
|
||||
}
|
||||
}
|
||||
return $cache[$string];
|
||||
}
|
||||
}
|
||||
88
inc/3rdparty/simplepie/SimplePie/Rating.php
vendored
88
inc/3rdparty/simplepie/SimplePie/Rating.php
vendored
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Rating
|
||||
{
|
||||
var $scheme;
|
||||
var $value;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($scheme = null, $value = null)
|
||||
{
|
||||
$this->scheme = $scheme;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value()
|
||||
{
|
||||
if ($this->value !== null)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
102
inc/3rdparty/simplepie/SimplePie/Restriction.php
vendored
102
inc/3rdparty/simplepie/SimplePie/Restriction.php
vendored
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Restriction
|
||||
{
|
||||
var $relationship;
|
||||
var $type;
|
||||
var $value;
|
||||
|
||||
// Constructor, used to input the data
|
||||
public function __construct($relationship = null, $type = null, $value = null)
|
||||
{
|
||||
$this->relationship = $relationship;
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
public function get_relationship()
|
||||
{
|
||||
if ($this->relationship !== null)
|
||||
{
|
||||
return $this->relationship;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_type()
|
||||
{
|
||||
if ($this->type !== null)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value()
|
||||
{
|
||||
if ($this->value !== null)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
400
inc/3rdparty/simplepie/SimplePie/Sanitize.php
vendored
400
inc/3rdparty/simplepie/SimplePie/Sanitize.php
vendored
@ -1,400 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
|
||||
*/
|
||||
class SimplePie_Sanitize
|
||||
{
|
||||
// Private vars
|
||||
var $base;
|
||||
|
||||
// Options
|
||||
var $remove_div = true;
|
||||
var $image_handler = '';
|
||||
var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
|
||||
var $encode_instead_of_strip = false;
|
||||
var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
|
||||
var $strip_comments = false;
|
||||
var $output_encoding = 'UTF-8';
|
||||
var $enable_cache = true;
|
||||
var $cache_location = './cache';
|
||||
var $cache_name_function = 'md5';
|
||||
var $cache_class = 'SimplePie_Cache';
|
||||
var $file_class = 'SimplePie_File';
|
||||
var $timeout = 10;
|
||||
var $useragent = '';
|
||||
var $force_fsockopen = false;
|
||||
|
||||
var $replace_url_attributes = array(
|
||||
'a' => 'href',
|
||||
'area' => 'href',
|
||||
'blockquote' => 'cite',
|
||||
'del' => 'cite',
|
||||
'form' => 'action',
|
||||
'img' => array('longdesc', 'src'),
|
||||
'input' => 'src',
|
||||
'ins' => 'cite',
|
||||
'q' => 'cite'
|
||||
);
|
||||
|
||||
public function remove_div($enable = true)
|
||||
{
|
||||
$this->remove_div = (bool) $enable;
|
||||
}
|
||||
|
||||
public function set_image_handler($page = false)
|
||||
{
|
||||
if ($page)
|
||||
{
|
||||
$this->image_handler = (string) $page;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->image_handler = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
|
||||
{
|
||||
if (isset($enable_cache))
|
||||
{
|
||||
$this->enable_cache = (bool) $enable_cache;
|
||||
}
|
||||
|
||||
if ($cache_location)
|
||||
{
|
||||
$this->cache_location = (string) $cache_location;
|
||||
}
|
||||
|
||||
if ($cache_name_function)
|
||||
{
|
||||
$this->cache_name_function = (string) $cache_name_function;
|
||||
}
|
||||
|
||||
if ($cache_class)
|
||||
{
|
||||
$this->cache_class = (string) $cache_class;
|
||||
}
|
||||
}
|
||||
|
||||
public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
|
||||
{
|
||||
if ($file_class)
|
||||
{
|
||||
$this->file_class = (string) $file_class;
|
||||
}
|
||||
|
||||
if ($timeout)
|
||||
{
|
||||
$this->timeout = (string) $timeout;
|
||||
}
|
||||
|
||||
if ($useragent)
|
||||
{
|
||||
$this->useragent = (string) $useragent;
|
||||
}
|
||||
|
||||
if ($force_fsockopen)
|
||||
{
|
||||
$this->force_fsockopen = (string) $force_fsockopen;
|
||||
}
|
||||
}
|
||||
|
||||
public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
|
||||
{
|
||||
if ($tags)
|
||||
{
|
||||
if (is_array($tags))
|
||||
{
|
||||
$this->strip_htmltags = $tags;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_htmltags = explode(',', $tags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_htmltags = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encode_instead_of_strip($encode = false)
|
||||
{
|
||||
$this->encode_instead_of_strip = (bool) $encode;
|
||||
}
|
||||
|
||||
public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
|
||||
{
|
||||
if ($attribs)
|
||||
{
|
||||
if (is_array($attribs))
|
||||
{
|
||||
$this->strip_attributes = $attribs;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_attributes = explode(',', $attribs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_attributes = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function strip_comments($strip = false)
|
||||
{
|
||||
$this->strip_comments = (bool) $strip;
|
||||
}
|
||||
|
||||
public function set_output_encoding($encoding = 'UTF-8')
|
||||
{
|
||||
$this->output_encoding = (string) $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set element/attribute key/value pairs of HTML attributes
|
||||
* containing URLs that need to be resolved relative to the feed
|
||||
*
|
||||
* @access public
|
||||
* @since 1.0
|
||||
* @param array $element_attribute Element/attribute key/value pairs
|
||||
*/
|
||||
public function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
|
||||
{
|
||||
$this->replace_url_attributes = (array) $element_attribute;
|
||||
}
|
||||
|
||||
public function sanitize($data, $type, $base = '')
|
||||
{
|
||||
$data = trim($data);
|
||||
if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
|
||||
{
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
|
||||
{
|
||||
if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
|
||||
{
|
||||
$type |= SIMPLEPIE_CONSTRUCT_HTML;
|
||||
}
|
||||
else
|
||||
{
|
||||
$type |= SIMPLEPIE_CONSTRUCT_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
|
||||
{
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
|
||||
{
|
||||
if ($this->remove_div)
|
||||
{
|
||||
$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
|
||||
$data = preg_replace('/<\/div>$/', '', $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
|
||||
{
|
||||
// Strip comments
|
||||
if ($this->strip_comments)
|
||||
{
|
||||
$data = SimplePie_Misc::strip_comments($data);
|
||||
}
|
||||
|
||||
// Strip out HTML tags and attributes that might cause various security problems.
|
||||
// Based on recommendations by Mark Pilgrim at:
|
||||
// http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
|
||||
if ($this->strip_htmltags)
|
||||
{
|
||||
foreach ($this->strip_htmltags as $tag)
|
||||
{
|
||||
$pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
|
||||
while (preg_match($pcre, $data))
|
||||
{
|
||||
$data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->strip_attributes)
|
||||
{
|
||||
foreach ($this->strip_attributes as $attrib)
|
||||
{
|
||||
$data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace relative URLs
|
||||
$this->base = $base;
|
||||
foreach ($this->replace_url_attributes as $element => $attributes)
|
||||
{
|
||||
$data = $this->replace_urls($data, $element, $attributes);
|
||||
}
|
||||
|
||||
// If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
|
||||
if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
|
||||
{
|
||||
$images = SimplePie_Misc::get_element('img', $data);
|
||||
foreach ($images as $img)
|
||||
{
|
||||
if (isset($img['attribs']['src']['data']))
|
||||
{
|
||||
$image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
|
||||
$cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
|
||||
|
||||
if ($cache->load())
|
||||
{
|
||||
$img['attribs']['src']['data'] = $this->image_handler . $image_url;
|
||||
$data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
|
||||
$headers = $file->headers;
|
||||
|
||||
if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
|
||||
{
|
||||
if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
|
||||
{
|
||||
$img['attribs']['src']['data'] = $this->image_handler . $image_url;
|
||||
$data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
|
||||
$data = trim($data);
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_IRI)
|
||||
{
|
||||
$data = SimplePie_Misc::absolutize_url($data, $base);
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
|
||||
{
|
||||
$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
||||
if ($this->output_encoding !== 'UTF-8')
|
||||
{
|
||||
$data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function replace_urls($data, $tag, $attributes)
|
||||
{
|
||||
if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
|
||||
{
|
||||
$elements = SimplePie_Misc::get_element($tag, $data);
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
if (is_array($attributes))
|
||||
{
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
if (isset($element['attribs'][$attribute]['data']))
|
||||
{
|
||||
$element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
|
||||
$new_element = SimplePie_Misc::element_implode($element);
|
||||
$data = str_replace($element['full'], $new_element, $data);
|
||||
$element['full'] = $new_element;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (isset($element['attribs'][$attributes]['data']))
|
||||
{
|
||||
$element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
|
||||
$data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function do_strip_htmltags($match)
|
||||
{
|
||||
if ($this->encode_instead_of_strip)
|
||||
{
|
||||
if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
|
||||
{
|
||||
$match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
|
||||
$match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
|
||||
return "<$match[1]$match[2]>$match[3]</$match[1]>";
|
||||
}
|
||||
else
|
||||
{
|
||||
return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
}
|
||||
elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
|
||||
{
|
||||
return $match[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
597
inc/3rdparty/simplepie/SimplePie/Source.php
vendored
597
inc/3rdparty/simplepie/SimplePie/Source.php
vendored
@ -1,597 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
class SimplePie_Source
|
||||
{
|
||||
var $item;
|
||||
var $data = array();
|
||||
|
||||
public function __construct($item, $data)
|
||||
{
|
||||
$this->item = $item;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return md5(serialize($this->data));
|
||||
}
|
||||
|
||||
public function get_source_tags($namespace, $tag)
|
||||
{
|
||||
if (isset($this->data['child'][$namespace][$tag]))
|
||||
{
|
||||
return $this->data['child'][$namespace][$tag];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_base($element = array())
|
||||
{
|
||||
return $this->item->get_base($element);
|
||||
}
|
||||
|
||||
public function sanitize($data, $type, $base = '')
|
||||
{
|
||||
return $this->item->sanitize($data, $type, $base);
|
||||
}
|
||||
|
||||
public function get_item()
|
||||
{
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
public function get_title()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_category($key = 0)
|
||||
{
|
||||
$categories = $this->get_categories();
|
||||
if (isset($categories[$key]))
|
||||
{
|
||||
return $categories[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_categories()
|
||||
{
|
||||
$categories = array();
|
||||
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
|
||||
{
|
||||
$term = null;
|
||||
$scheme = null;
|
||||
$label = null;
|
||||
if (isset($category['attribs']['']['term']))
|
||||
{
|
||||
$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['scheme']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['label']))
|
||||
{
|
||||
$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
$categories[] = new $this->item->feed->category_class($term, $scheme, $label);
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
|
||||
{
|
||||
// This is really the label, but keep this as the term also for BC.
|
||||
// Label will also work on retrieving because that falls back to term.
|
||||
$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
if (isset($category['attribs']['']['domain']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
$scheme = null;
|
||||
}
|
||||
$categories[] = new $this->item->feed->category_class($term, $scheme, null);
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
|
||||
{
|
||||
$categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
|
||||
{
|
||||
$categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
|
||||
}
|
||||
|
||||
if (!empty($categories))
|
||||
{
|
||||
return SimplePie_Misc::array_unique($categories);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_author($key = 0)
|
||||
{
|
||||
$authors = $this->get_authors();
|
||||
if (isset($authors[$key]))
|
||||
{
|
||||
return $authors[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_authors()
|
||||
{
|
||||
$authors = array();
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
|
||||
{
|
||||
$name = null;
|
||||
$uri = null;
|
||||
$email = null;
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
|
||||
{
|
||||
$uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
|
||||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $uri !== null)
|
||||
{
|
||||
$authors[] = new $this->item->feed->author_class($name, $uri, $email);
|
||||
}
|
||||
}
|
||||
if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
|
||||
{
|
||||
$name = null;
|
||||
$url = null;
|
||||
$email = null;
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
|
||||
{
|
||||
$url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
|
||||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $url !== null)
|
||||
{
|
||||
$authors[] = new $this->item->feed->author_class($name, $url, $email);
|
||||
}
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
|
||||
{
|
||||
$authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
|
||||
{
|
||||
$authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
|
||||
{
|
||||
$authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
|
||||
}
|
||||
|
||||
if (!empty($authors))
|
||||
{
|
||||
return SimplePie_Misc::array_unique($authors);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_contributor($key = 0)
|
||||
{
|
||||
$contributors = $this->get_contributors();
|
||||
if (isset($contributors[$key]))
|
||||
{
|
||||
return $contributors[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_contributors()
|
||||
{
|
||||
$contributors = array();
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
|
||||
{
|
||||
$name = null;
|
||||
$uri = null;
|
||||
$email = null;
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
|
||||
{
|
||||
$uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $uri !== null)
|
||||
{
|
||||
$contributors[] = new $this->item->feed->author_class($name, $uri, $email);
|
||||
}
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
|
||||
{
|
||||
$name = null;
|
||||
$url = null;
|
||||
$email = null;
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
|
||||
{
|
||||
$url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $url !== null)
|
||||
{
|
||||
$contributors[] = new $this->item->feed->author_class($name, $url, $email);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contributors))
|
||||
{
|
||||
return SimplePie_Misc::array_unique($contributors);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_link($key = 0, $rel = 'alternate')
|
||||
{
|
||||
$links = $this->get_links($rel);
|
||||
if (isset($links[$key]))
|
||||
{
|
||||
return $links[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Added for parity between the parent-level and the item/entry-level.
|
||||
*/
|
||||
public function get_permalink()
|
||||
{
|
||||
return $this->get_link(0);
|
||||
}
|
||||
|
||||
public function get_links($rel = 'alternate')
|
||||
{
|
||||
if (!isset($this->data['links']))
|
||||
{
|
||||
$this->data['links'] = array();
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
|
||||
{
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if (isset($link['attribs']['']['href']))
|
||||
{
|
||||
$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
|
||||
$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
|
||||
{
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if (isset($link['attribs']['']['href']))
|
||||
{
|
||||
$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
|
||||
$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
|
||||
$keys = array_keys($this->data['links']);
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
if (SimplePie_Misc::is_isegment_nz_nc($key))
|
||||
{
|
||||
if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
|
||||
{
|
||||
$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
|
||||
$this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
|
||||
}
|
||||
}
|
||||
elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
|
||||
{
|
||||
$this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
|
||||
}
|
||||
$this->data['links'][$key] = array_unique($this->data['links'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->data['links'][$rel]))
|
||||
{
|
||||
return $this->data['links'][$rel];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_copyright()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_language()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif (isset($this->data['xml_lang']))
|
||||
{
|
||||
return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_latitude()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
|
||||
{
|
||||
return (float) $match[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_longitude()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
|
||||
{
|
||||
return (float) $match[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_image_url()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
|
||||
{
|
||||
return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,362 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Parses the XML Declaration
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_XML_Declaration_Parser
|
||||
{
|
||||
/**
|
||||
* XML Version
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $version = '1.0';
|
||||
|
||||
/**
|
||||
* Encoding
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Standalone
|
||||
*
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
var $standalone = false;
|
||||
|
||||
/**
|
||||
* Current state of the state machine
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $state = 'before_version_name';
|
||||
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $data = '';
|
||||
|
||||
/**
|
||||
* Input data length (to avoid calling strlen() everytime this is needed)
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $data_length = 0;
|
||||
|
||||
/**
|
||||
* Current position of the pointer
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $position = 0;
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input data
|
||||
*
|
||||
* @access public
|
||||
* @param string $data Input data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->data_length = strlen($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input data
|
||||
*
|
||||
* @access public
|
||||
* @return bool true on success, false on failure
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
while ($this->state && $this->state !== 'emit' && $this->has_data())
|
||||
{
|
||||
$state = $this->state;
|
||||
$this->$state();
|
||||
}
|
||||
$this->data = '';
|
||||
if ($this->state === 'emit')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->version = '';
|
||||
$this->encoding = '';
|
||||
$this->standalone = '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is data beyond the pointer
|
||||
*
|
||||
* @access private
|
||||
* @return bool true if there is further data, false if not
|
||||
*/
|
||||
public function has_data()
|
||||
{
|
||||
return (bool) ($this->position < $this->data_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance past any whitespace
|
||||
*
|
||||
* @return int Number of whitespace characters passed
|
||||
*/
|
||||
public function skip_whitespace()
|
||||
{
|
||||
$whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
|
||||
$this->position += $whitespace;
|
||||
return $whitespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read value
|
||||
*/
|
||||
public function get_value()
|
||||
{
|
||||
$quote = substr($this->data, $this->position, 1);
|
||||
if ($quote === '"' || $quote === "'")
|
||||
{
|
||||
$this->position++;
|
||||
$len = strcspn($this->data, $quote, $this->position);
|
||||
if ($this->has_data())
|
||||
{
|
||||
$value = substr($this->data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function before_version_name()
|
||||
{
|
||||
if ($this->skip_whitespace())
|
||||
{
|
||||
$this->state = 'version_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 7) === 'version')
|
||||
{
|
||||
$this->position += 7;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'version_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'version_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_value()
|
||||
{
|
||||
if ($this->version = $this->get_value())
|
||||
{
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = 'encoding_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 8) === 'encoding')
|
||||
{
|
||||
$this->position += 8;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'encoding_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'standalone_name';
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'encoding_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_value()
|
||||
{
|
||||
if ($this->encoding = $this->get_value())
|
||||
{
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = 'standalone_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 10) === 'standalone')
|
||||
{
|
||||
$this->position += 10;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'standalone_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'standalone_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_value()
|
||||
{
|
||||
if ($standalone = $this->get_value())
|
||||
{
|
||||
switch ($standalone)
|
||||
{
|
||||
case 'yes':
|
||||
$this->standalone = true;
|
||||
break;
|
||||
|
||||
case 'no':
|
||||
$this->standalone = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
355
inc/3rdparty/simplepie/SimplePie/gzdecode.php
vendored
355
inc/3rdparty/simplepie/SimplePie/gzdecode.php
vendored
@ -1,355 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* gzdecode
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_gzdecode
|
||||
{
|
||||
/**
|
||||
* Compressed data
|
||||
*
|
||||
* @access private
|
||||
* @see gzdecode::$data
|
||||
*/
|
||||
var $compressed_data;
|
||||
|
||||
/**
|
||||
* Size of compressed data
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $compressed_size;
|
||||
|
||||
/**
|
||||
* Minimum size of a valid gzip string
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $min_compressed_size = 18;
|
||||
|
||||
/**
|
||||
* Current position of pointer
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $position = 0;
|
||||
|
||||
/**
|
||||
* Flags (FLG)
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $flags;
|
||||
|
||||
/**
|
||||
* Uncompressed data
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$compressed_data
|
||||
*/
|
||||
var $data;
|
||||
|
||||
/**
|
||||
* Modified time
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $MTIME;
|
||||
|
||||
/**
|
||||
* Extra Flags
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $XFL;
|
||||
|
||||
/**
|
||||
* Operating System
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $OS;
|
||||
|
||||
/**
|
||||
* Subfield ID 1
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI2
|
||||
*/
|
||||
var $SI1;
|
||||
|
||||
/**
|
||||
* Subfield ID 2
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI1
|
||||
*/
|
||||
var $SI2;
|
||||
|
||||
/**
|
||||
* Extra field content
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$SI1
|
||||
* @see gzdecode::$SI2
|
||||
*/
|
||||
var $extra_field;
|
||||
|
||||
/**
|
||||
* Original filename
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $filename;
|
||||
|
||||
/**
|
||||
* Human readable comment
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
var $comment;
|
||||
|
||||
/**
|
||||
* Don't allow anything to be set
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
trigger_error("Cannot write property $name", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compressed string and related properties
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->compressed_data = $data;
|
||||
$this->compressed_size = strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the GZIP stream
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Check ID1, ID2, and CM
|
||||
if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the FLG (FLaGs)
|
||||
$this->flags = ord($this->compressed_data[3]);
|
||||
|
||||
// FLG bits above (1 << 4) are reserved
|
||||
if ($this->flags > 0x1F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance the pointer after the above
|
||||
$this->position += 4;
|
||||
|
||||
// MTIME
|
||||
$mtime = substr($this->compressed_data, $this->position, 4);
|
||||
// Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
|
||||
if (current(unpack('S', "\x00\x01")) === 1)
|
||||
{
|
||||
$mtime = strrev($mtime);
|
||||
}
|
||||
$this->MTIME = current(unpack('l', $mtime));
|
||||
$this->position += 4;
|
||||
|
||||
// Get the XFL (eXtra FLags)
|
||||
$this->XFL = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Get the OS (Operating System)
|
||||
$this->OS = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Parse the FEXTRA
|
||||
if ($this->flags & 4)
|
||||
{
|
||||
// Read subfield IDs
|
||||
$this->SI1 = $this->compressed_data[$this->position++];
|
||||
$this->SI2 = $this->compressed_data[$this->position++];
|
||||
|
||||
// SI2 set to zero is reserved for future use
|
||||
if ($this->SI2 === "\x00")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the length of the extra field
|
||||
$len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
$this->position += 2;
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 4;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the extra field to the given data
|
||||
$this->extra_field = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FNAME
|
||||
if ($this->flags & 8)
|
||||
{
|
||||
// Get the length of the filename
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original filename to the given string
|
||||
$this->filename = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FCOMMENT
|
||||
if ($this->flags & 16)
|
||||
{
|
||||
// Get the length of the comment
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original comment to the given string
|
||||
$this->comment = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FHCRC
|
||||
if ($this->flags & 2)
|
||||
{
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 2;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Read the CRC
|
||||
$crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
|
||||
// Check the CRC matches
|
||||
if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
|
||||
{
|
||||
$this->position += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Decompress the actual data
|
||||
if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->position = $this->compressed_size - 8;
|
||||
}
|
||||
|
||||
// Check CRC of data
|
||||
$crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
/*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Check ISIZE of data
|
||||
$isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wow, against all odds, we've actually got a valid gzip string
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
inc/3rdparty/simplepie/SimplePieAutoloader.php
vendored
80
inc/3rdparty/simplepie/SimplePieAutoloader.php
vendored
@ -1,80 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
|
||||
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3-dev
|
||||
* @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
* @todo phpDoc comments
|
||||
*/
|
||||
|
||||
|
||||
// autoloader
|
||||
spl_autoload_register(array(new SimplePie_Autoloader(), 'autoload'));
|
||||
|
||||
/**
|
||||
* SimplePie Autoloader class.
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Autoloader
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->path = dirname(__FILE__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader.
|
||||
*
|
||||
* @param string $class The name of the class to attempt to load.
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
// see if this request should be handled by this autoloader
|
||||
if (strpos($class, 'SimplePie') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $this->path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
|
||||
include $filename;
|
||||
}
|
||||
}
|
||||
6
inc/3rdparty/site_config/README.md
vendored
6
inc/3rdparty/site_config/README.md
vendored
@ -1,6 +0,0 @@
|
||||
Full-Text RSS Site Patterns
|
||||
---------------------------
|
||||
|
||||
Site patterns allow you to specify what should be extracted from specific sites.
|
||||
|
||||
Please see http://help.fivefilters.org/customer/portal/articles/223153-site-patterns for more information.
|
||||
@ -1,6 +0,0 @@
|
||||
title: //title
|
||||
body: //h2 | //span[@class='masque'] | //article[@class='corps_article_right']
|
||||
prune: no
|
||||
tidy: no
|
||||
|
||||
test_url: http://www.bfmtv.com/societe/cigarette-electronique-dangers-588622.html
|
||||
@ -1,4 +0,0 @@
|
||||
title: //div[contains(@class, 'SB_Title')]//a
|
||||
body: //div[contains(@class, 'STR_Content')]
|
||||
|
||||
test_url: http://dilbert.com/strips/comic/2013-10-22
|
||||
@ -1,7 +0,0 @@
|
||||
title: //title
|
||||
body: //div[@class='post-content']
|
||||
|
||||
prune: no
|
||||
tidy: no
|
||||
|
||||
test_url: http://www.inthepoche.com/?post/poche-hosting
|
||||
6
inc/3rdparty/site_config/custom/tldp.org.txt
vendored
6
inc/3rdparty/site_config/custom/tldp.org.txt
vendored
@ -1,6 +0,0 @@
|
||||
title: //title
|
||||
body: //h2 | //p | //ul
|
||||
prune: no
|
||||
tidy: no
|
||||
|
||||
test_url: http://www.tldp.org/HOWTO/Plug-and-Play-HOWTO-7.html
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user