Compare commits
2654 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb7896b2bd | |||
| aecb3d5fed | |||
| e87ab8729d | |||
| 4b39011d69 | |||
| e34e0db1e5 | |||
| dfc41df02a | |||
| 72f555d9a6 | |||
| dbf21c3df5 | |||
| 78de4c894b | |||
| 02a49c8735 | |||
| d4fe793820 | |||
| fd90812453 | |||
| f1d2025b39 | |||
| 60a06c1706 | |||
| 741a0c3508 | |||
| 2bb2b5c9de | |||
| 7883b5931f | |||
| 98099b6a02 | |||
| a615ddc57d | |||
| f98d4304b1 | |||
| e6202fcf23 | |||
| 4aefefc295 | |||
| 51d88128f4 | |||
| 73ea0c4b1e | |||
| a8ac90c466 | |||
| d78724b4c9 | |||
| 022b68e3b3 | |||
| 6733151051 | |||
| 0d667ba503 | |||
| bb9cca20ba | |||
| e4c333dded | |||
| 5bd9c6a3b4 | |||
| a30457892d | |||
| 32d0a6bf4f | |||
| 59e569e59f | |||
| db5c7089bb | |||
| 7e27920421 | |||
| 128a25e6d5 | |||
| 4619ce1e03 | |||
| e84bc1aa80 | |||
| cc4e9f953e | |||
| 58df7bcea5 | |||
| f94b16e7ca | |||
| 9d18a74440 | |||
| 864782d48d | |||
| b536a9dcce | |||
| 0d981fcb86 | |||
| 2f71892daf | |||
| 55061e4dc7 | |||
| 668363eb1b | |||
| 2c7f40aa1e | |||
| d93674485d | |||
| aa12313ee4 | |||
| 62a3624f1f | |||
| 6fafd4964a | |||
| 1fb1a6647f | |||
| 020ca7f651 | |||
| 7faa1cb195 | |||
| 7af3980f96 | |||
| 68bb6fbeb9 | |||
| e35898342d | |||
| 74b9251c40 | |||
| f9fc569c5d | |||
| d97acf8b05 | |||
| c3db29a036 | |||
| 6003c72b5c | |||
| 400c662462 | |||
| 7e5f63d9d2 | |||
| d4f09b7821 | |||
| bdff9336e5 | |||
| 8c92422bce | |||
| 4f49833fc9 | |||
| 1db631bab3 | |||
| 4267203a64 | |||
| fd9e77a4c8 | |||
| a7c9193e03 | |||
| dd0e242ac0 | |||
| 1c1c11f31f | |||
| 2cc8655ed2 | |||
| 2fb79a5961 | |||
| 33dcbbe2ef | |||
| 7116e167fe | |||
| b043b45a1e | |||
| fb1de8ac51 | |||
| 55a9bc66b2 | |||
| 93322d2dce | |||
| c3df4cc0c4 | |||
| c0e626fecf | |||
| 7e9524c7bb | |||
| eb13701244 | |||
| a47fa22ca4 | |||
| 69f8eae646 | |||
| 8da2f97d07 | |||
| b0a33ec353 | |||
| 8d4a0e7e9f | |||
| 0af650be44 | |||
| 7f7f452388 | |||
| d4ce2533f6 | |||
| ed37d4ba16 | |||
| c2ff0e9ffa | |||
| c33790674a | |||
| 1a99a8dd65 | |||
| 227d115d71 | |||
| 3fe8959d00 | |||
| fb0fc710a3 | |||
| 47b0fc5219 | |||
| c0ede6cf6a | |||
| 197edb2730 | |||
| c29849f06a | |||
| a8218e8de3 | |||
| 4c9d8817b7 | |||
| 8e899414fb | |||
| adfb3bc537 | |||
| 34cefef45f | |||
| b73214abba | |||
| 5dba47f945 | |||
| 1bf557e307 | |||
| f94c85c8e1 | |||
| 3d7b8fa803 | |||
| a78094a7aa | |||
| b386099b49 | |||
| cc60537436 | |||
| 23a0a76d93 | |||
| 3f6ac66970 | |||
| 004a597837 | |||
| 926da9c59a | |||
| 99d488d1be | |||
| 0bcb16cc59 | |||
| 469b783b2c | |||
| 6be46c890e | |||
| 812219e372 | |||
| 82e6d490b4 | |||
| 2db0531fa9 | |||
| d53c4c1ce9 | |||
| d4bfdd3039 | |||
| f7bfa7123b | |||
| d2cdb8f2ba | |||
| 99ea373eb7 | |||
| ff4b63ed14 | |||
| 1b67de854d | |||
| 1196bbe826 | |||
| 8bf485fd1d | |||
| d8edd18c10 | |||
| 97c43af83e | |||
| 797da0eae1 | |||
| 00f5a6f940 | |||
| e51533bc31 | |||
| a9a22cce36 | |||
| 1dfddafcf5 | |||
| 801d47eb8d | |||
| b5d6fc0a39 | |||
| e8818b76d4 | |||
| b19bd737d3 | |||
| 96316701e4 | |||
| 427d2d61c1 | |||
| 2a733ffe17 | |||
| b2257b7640 | |||
| 5c9714fa54 | |||
| dfb036c7f2 | |||
| 1a0672cb78 | |||
| 7cd98fb1f9 | |||
| 363579c370 | |||
| 3fb15d74a8 | |||
| 155de9a352 | |||
| b69ebc5c67 | |||
| ff7ad0f287 | |||
| c6af20c86c | |||
| 62c36fb1a0 | |||
| 6184480b06 | |||
| e2ccf68c03 | |||
| 112f929814 | |||
| 69d157062c | |||
| a3f7958830 | |||
| c98e858886 | |||
| 9fe8fb960b | |||
| 2d7947eb93 | |||
| 148e644590 | |||
| 0003150796 | |||
| d4dbbe53af | |||
| 30982e446d | |||
| 6001a9aaf4 | |||
| 1935ae6979 | |||
| 6029627a5f | |||
| f67ba78513 | |||
| 2cec984288 | |||
| fe90ba6b5d | |||
| c635de6e85 | |||
| e6077f5ac7 | |||
| d5398e4691 | |||
| d4be55a236 | |||
| c16e034f7c | |||
| b98117f821 | |||
| 5edc71f31a | |||
| 96a929df0b | |||
| a2fdadfaed | |||
| 0692dfb67e | |||
| 7120d50bf6 | |||
| 0f12a87e31 | |||
| d38ea97fa4 | |||
| 8897bf5e4d | |||
| 2a228f68cf | |||
| 3eb59e9052 | |||
| 2c7cd731d9 | |||
| e128394360 | |||
| e672cf5350 | |||
| cfa8d8ff6e | |||
| 7fe8d91bc2 | |||
| bb0bae1cd9 | |||
| 90eed2d001 | |||
| 7fd42fde05 | |||
| fe6fc9eb74 | |||
| 751840ba10 | |||
| 077425689d | |||
| fa1ca78ea7 | |||
| 6aae658e7f | |||
| 04104a3e4d | |||
| 150d748c67 | |||
| 4a565a89da | |||
| a06e00d4af | |||
| 4420267709 | |||
| cde889101b | |||
| 897337cb8e | |||
| 98acb4963d | |||
| c7e6e6be8d | |||
| f0268dabb0 | |||
| 609332a03a | |||
| c3273fba0d | |||
| 0905633810 | |||
| 3391f5946e | |||
| 73e15645d6 | |||
| 4d7b90af99 | |||
| 1965d2d419 | |||
| f2f4855ed7 | |||
| ee1e567503 | |||
| d1baaf4983 | |||
| 52730e6b0e | |||
| 26d18490d4 | |||
| b0e4a4e6f5 | |||
| dd4371a97c | |||
| a7732eeb81 | |||
| 715d8cafa6 | |||
| ecd3ba5a10 | |||
| bb87f4dd6b | |||
| 661f383edc | |||
| afb4cdc685 | |||
| 8fcf4cd652 | |||
| 3030b80c2b | |||
| 732d6067c3 | |||
| 657db63432 | |||
| e251e5e509 | |||
| 0d7f8d474f | |||
| 7801b33e35 | |||
| 7554623cff | |||
| d130dc729e | |||
| 92299999e7 | |||
| 8fb7d51106 | |||
| b3dc10cc7c | |||
| 471a4b15a8 | |||
| 0d75d4ff88 | |||
| 6777f89078 | |||
| e987751b19 | |||
| 73c178a3ea | |||
| 08c09d1d65 | |||
| 5be90fd7ea | |||
| 2878c154d6 | |||
| 2e43a9944e | |||
| 4539ef8d9d | |||
| 994161a0a2 | |||
| e2b6417bd2 | |||
| 2b9a008208 | |||
| 8c732e94ab | |||
| e4d4b7118c | |||
| 167cbdd17c | |||
| e6bb6005ec | |||
| 40e9a5b7b3 | |||
| b105caff07 | |||
| a9eb4be896 | |||
| de82c49fb3 | |||
| fdc7c089c2 | |||
| 2b610dc791 | |||
| 7c21de8aa8 | |||
| d7b1e7d23d | |||
| 9e49ecc8c3 | |||
| d9b48b8efe | |||
| e1402db6cc | |||
| 5c50484068 | |||
| 1e1e196e10 | |||
| 7ceb1a711e | |||
| 3fca094dfa | |||
| 15dacd15ec | |||
| 4f2ea4de8a | |||
| 507dc05998 | |||
| 40ea9d2dc0 | |||
| 03a94807eb | |||
| d8a82090cb | |||
| 8ac718a606 | |||
| 44d0be4604 | |||
| 1508a0f53f | |||
| 61fe3e2bf9 | |||
| 72bfb9a515 | |||
| 5a6e1868a8 | |||
| a10d9e4b80 | |||
| 7760786e7e | |||
| f63d884cfe | |||
| 80716280a8 | |||
| 44689dead7 | |||
| a8d00a8080 | |||
| f85f83c337 | |||
| c80fc3dff8 | |||
| 300bdd6f5f | |||
| a3c567e864 | |||
| 13616f49f3 | |||
| 3da11862c2 | |||
| 4c94dcba5c | |||
| df17a410b0 | |||
| ea08cd429a | |||
| a0527ca81b | |||
| a5d5e7d940 | |||
| d5eae21a9c | |||
| 6b9f08a1fe | |||
| ce8917d3a0 | |||
| d05ae52575 | |||
| 72bcd36ef1 | |||
| 8b8dcfd968 | |||
| d0994583ce | |||
| 0047140dcc | |||
| 56b26f7120 | |||
| 5934095301 | |||
| 86b6c8ce49 | |||
| c65c9e786f | |||
| 67bfde277a | |||
| 55ae435c89 | |||
| c8b4faf93a | |||
| d0dc9da015 | |||
| 405847cac6 | |||
| 7e03be6930 | |||
| 180e110f50 | |||
| fd3498a1f8 | |||
| fcab850687 | |||
| 4bb10f5b70 | |||
| 6c561a6875 | |||
| 3f645612e0 | |||
| 6fd7dcc3b5 | |||
| 3e7f521936 | |||
| 9173e046e5 | |||
| 517a3c4dfe | |||
| b5a5b0a996 | |||
| e6ae8f0920 | |||
| 6cd46eed6b | |||
| 00be5d7b4c | |||
| 0a72ce8c19 | |||
| c4f9b721e7 | |||
| b9d1fa38c9 | |||
| b00343d24d | |||
| b9b55142fc | |||
| aaca8eda3b | |||
| 8954e6ec7e | |||
| 7a6ab5fcf8 | |||
| c7d66927b2 | |||
| 32769998df | |||
| 613119e964 | |||
| 5de0eb4c80 | |||
| 43fb606b3c | |||
| 86ab8c62b1 | |||
| e6cab58414 | |||
| 2f06e28f23 | |||
| 9efb1665ad | |||
| 755fe60075 | |||
| 2e63945f60 | |||
| 241f223536 | |||
| 13775ba4b2 | |||
| 1dcab7a7e6 | |||
| c6031dc1dc | |||
| 4a0c591657 | |||
| c94d8fa93b | |||
| 14d06815b7 | |||
| 0d5d67b20e | |||
| 531ccfc0a0 | |||
| 64f32ef864 | |||
| 49ed5fcc42 | |||
| 4ecb13a3be | |||
| a7d4e0111d | |||
| a148f7b227 | |||
| ce57ec8a38 | |||
| da635a0ebe | |||
| 995917db93 | |||
| 0d71cac44a | |||
| 171a501cb5 | |||
| bb2c5a63d0 | |||
| fbc8e55d09 | |||
| 0a1cb87151 | |||
| b19d6137fb | |||
| 25e374848f | |||
| 97d9f5ce31 | |||
| 94f99a9ce2 | |||
| 28d00949f4 | |||
| 1c33d93a18 | |||
| e78648b8c7 | |||
| 3b6d12ce2d | |||
| 1b1a130e38 | |||
| eaee2d1f3a | |||
| 1e6fda11e7 | |||
| f38d72dec5 | |||
| 206dc56cab | |||
| 0125f1539e | |||
| 5056cd6409 | |||
| 780b7166b8 | |||
| 9715fe4b94 | |||
| 194e08b669 | |||
| ca30b24f75 | |||
| e4eb9a0d1f | |||
| ffa6493677 | |||
| a1854d4567 | |||
| e5f1364bda | |||
| 1712d9bb5b | |||
| 90a4b95b61 | |||
| 6fdde3a251 | |||
| 2616671c6e | |||
| 8112c39485 | |||
| c786d457a7 | |||
| 590d2d88ae | |||
| 980c304629 | |||
| 63786a41c2 | |||
| 70c4ce8e40 | |||
| b55d8a26f2 | |||
| b73eb367f2 | |||
| 9032f24f4b | |||
| 5985577fbe | |||
| e7d822be11 | |||
| 5f14b67e66 | |||
| 222cfe5c16 | |||
| 93e781048c | |||
| 8b863d5370 | |||
| 2970ac60a6 | |||
| 0fd299adf2 | |||
| 5398e2f72a | |||
| 6175559fda | |||
| d41d949642 | |||
| 0cce92d4d7 | |||
| 9278c9e40c | |||
| 98cd0e0541 | |||
| 5f59a811e8 | |||
| 104122925b | |||
| 31e58ff044 | |||
| 6b81f519e7 | |||
| 72f316712b | |||
| 872d978d63 | |||
| 863db549f7 | |||
| c249403c16 | |||
| 325ea6de7b | |||
| 2947081b41 | |||
| c705dddf8d | |||
| ffe581225c | |||
| 27cf643135 | |||
| 73dc7a9225 | |||
| 9ad1dd9312 | |||
| 88a4776891 | |||
| 8f88998c90 | |||
| 7c7dc58665 | |||
| 1062145b49 | |||
| 0eab8c6efa | |||
| 820ccc4709 | |||
| 7c51555438 | |||
| cabad4a933 | |||
| f800305abe | |||
| 94eb2b32de | |||
| 18bdf03623 | |||
| a2c77619dc | |||
| f5669177de | |||
| b76e117366 | |||
| bdd6c4fb17 | |||
| d84cd93c57 | |||
| 5ee05f1143 | |||
| 75397c7d47 | |||
| 811af79b16 | |||
| 12ddca1070 | |||
| 6954db1843 | |||
| e31078615b | |||
| ac7c8c0716 | |||
| b5b28450f3 | |||
| 18f75f5e7c | |||
| e932ad78b0 | |||
| e7502ef9bc | |||
| 7740886ff9 | |||
| a7c2d5b868 | |||
| ddac2c8048 | |||
| ef068314cb | |||
| 0e66dbd79a | |||
| c079c2e8b7 | |||
| 0f175d9478 | |||
| 9290ee29da | |||
| 3605937049 | |||
| 8323d9272d | |||
| e2ab5e9858 | |||
| b5af1289f2 | |||
| 79e4527163 | |||
| 430d364a88 | |||
| e5b7ef40d1 | |||
| d6ad3ad3c4 | |||
| b62516fcce | |||
| 6249a6af5e | |||
| 6f6410adb4 | |||
| 441bb6d56f | |||
| 0670bb86c1 | |||
| 1a15391b9a | |||
| d0a25a8f77 | |||
| eeb25b2b66 | |||
| a1e0f7c8e9 | |||
| d584a7febb | |||
| b204d8b179 | |||
| 3077b4747d | |||
| a576ee8ec9 | |||
| 8788403baa | |||
| 12eb66a669 | |||
| 4d0daa24d0 | |||
| 4665bb6598 | |||
| 02cf5a3f29 | |||
| a3a0ff7980 | |||
| 4030c2ffb0 | |||
| 3873d80ea8 | |||
| 3b36be9beb | |||
| 044f1f7dd5 | |||
| fa95f33fb1 | |||
| 22d3d1cf4b | |||
| 44a8d8d84d | |||
| 37fecb5ebe | |||
| 8795b06c73 | |||
| 17e13b609b | |||
| 67864f195f | |||
| 71aff1c671 | |||
| 02e0fa7b8e | |||
| e542dcb38a | |||
| f7c0fa23bc | |||
| 80b07eb2a2 | |||
| e11b27a2a1 | |||
| 0302f7d034 | |||
| 147a9ab43e | |||
| 11bbf39cc6 | |||
| 006bb855f4 | |||
| 9be0364003 | |||
| 71e41b3a5a | |||
| 5f7f2e5ce0 | |||
| 100c344a14 | |||
| df20e85811 | |||
| c3d6d57db3 | |||
| a99156a21d | |||
| 859e66d8af | |||
| 253428dd93 | |||
| a96ff42d61 | |||
| ca6ac5eef9 | |||
| a58cdb2902 | |||
| 797c56e015 | |||
| 463733b30b | |||
| b0a7d0a0d2 | |||
| ff5d1a3d5b | |||
| aa9f280240 | |||
| f223db6c59 | |||
| 9117b48176 | |||
| b63c4e1466 | |||
| be9d45eb73 | |||
| 8f857aaf04 | |||
| b92c805bc5 | |||
| 0530e3f789 | |||
| 265b3a6a08 | |||
| f1d7052770 | |||
| d6385b7754 | |||
| bb986c0546 | |||
| e483598fb3 | |||
| 3e7e6a03ed | |||
| ef90f8e157 | |||
| f2e7f6b2a0 | |||
| 4c29d1f236 | |||
| 9ed46b892f | |||
| e80daa7670 | |||
| a5d7dbc081 | |||
| 2c7a00aaad | |||
| dad7daf429 | |||
| ed880162cb | |||
| 24bdb147e0 | |||
| d375a00046 | |||
| 3d2b77e1b5 | |||
| 5b640b575c | |||
| 62d8cce314 | |||
| 1a0e039f6f | |||
| 2fbf1e32ff | |||
| 5c5eb9101d | |||
| 4b83f8dcce | |||
| dcb044fb28 | |||
| 4e8a896f84 | |||
| 8a464c060f | |||
| 1025ec5748 | |||
| 254ecb4c6a | |||
| 3902c88916 | |||
| f6438592c4 | |||
| 7fe1264f00 | |||
| 1448313fb8 | |||
| 1480e0a88b | |||
| 4ecc125adb | |||
| 709253498a | |||
| 0dc96ec9b8 | |||
| ee50524242 | |||
| 47afba18cb | |||
| 7c4f1f1052 | |||
| 148c67bf9b | |||
| d80deeb364 | |||
| ba8eb7eea8 | |||
| 6287ce8f7e | |||
| d626281228 | |||
| b295e617df | |||
| 4c97a041cc | |||
| 6dac0b5798 | |||
| a87c0fa755 | |||
| 0f2f437c8c | |||
| bdea7336ee | |||
| 5fdb253448 | |||
| 0eaf9db416 | |||
| 78d7c4984c | |||
| 4858687501 | |||
| a8e61fe115 | |||
| 1b9e5de787 | |||
| 9ab0e57389 | |||
| b07a835629 | |||
| 8b51c37b98 | |||
| 4a730bfcf0 | |||
| 43676a0918 | |||
| efed228527 | |||
| 0cce75c47c | |||
| d6ac2aacf0 | |||
| 05f14a9f5a | |||
| 4433f91e69 | |||
| 57304aa628 | |||
| 1eff19d1b0 | |||
| 12325943a1 | |||
| d758e6b591 | |||
| 9fbb248531 | |||
| 6ce61621a4 | |||
| a2130e3d89 | |||
| d49bc18718 | |||
| e29009d1ba | |||
| 7f6194e195 | |||
| adfb237b4a | |||
| afa74da11c | |||
| e571ca1def | |||
| e3867132ea | |||
| c348799a44 | |||
| 2944725b69 | |||
| d0affbb4e4 | |||
| 2a05ef7969 | |||
| bf7480863b | |||
| 2677f67a43 | |||
| 3df6aff87a | |||
| 79a972e92f | |||
| 0e56ffeba0 | |||
| d0af671d2f | |||
| ff3cd29f2a | |||
| 6646955b09 | |||
| d91aceb41e | |||
| 8cb627cb31 | |||
| b141f4a410 | |||
| 1ac7f7141c | |||
| c9ff0a414e | |||
| 4b13006687 | |||
| aa0b68d8c5 | |||
| 5723673ab3 | |||
| 1bf4137aba | |||
| d35b4d127d | |||
| 36cde3030a | |||
| 91412bf73b | |||
| 0dc26512a3 | |||
| f0ade5eda0 | |||
| 2f631807fe | |||
| c8e147874b | |||
| dc6d32bf68 | |||
| c3d060c973 | |||
| b3bb1f38fc | |||
| 24bb0112d9 | |||
| 3010116e97 | |||
| 48c9089f77 | |||
| aca77bd482 | |||
| ffe93c92fc | |||
| 698c6ce698 | |||
| 8b233d562e | |||
| 67a82a7e1d | |||
| 4466096c18 | |||
| 7e46e92e1b | |||
| d91b86486b | |||
| 0204a597c7 | |||
| 0ffd02cf1c | |||
| c004d90a6c | |||
| e64793a809 | |||
| 03cc73d77e | |||
| b835364dfd | |||
| 2f3170ef18 | |||
| abba5bdb15 | |||
| a319d59eed | |||
| a3cd4d555a | |||
| 21b277bd1c | |||
| cc6e5ec94d | |||
| ecd211479f | |||
| 1fb5bcf38e | |||
| b51b3dfb59 | |||
| 77033efcf4 | |||
| 94f161359e | |||
| 8eaffe46fe | |||
| fb9414b9ae | |||
| 85ef7dafc4 | |||
| cb00982db9 | |||
| 92e56848cf | |||
| efe2303b23 | |||
| 8da4c647a8 | |||
| 6d7e2f44a3 | |||
| 325de34183 | |||
| affa3a3638 | |||
| 4d17c0ae02 | |||
| 9545fcbbc9 | |||
| 2e1240ba22 | |||
| 73f417fe39 | |||
| eab43b12f5 | |||
| 26535ec09c | |||
| 92afc37753 | |||
| 6c26d1b3f6 | |||
| 8f894f50f1 | |||
| 35698284d6 | |||
| dc8fba51cc | |||
| d5f24aef12 | |||
| b41bda08bd | |||
| 313a843836 | |||
| 29fada318b | |||
| 4bac189d6d | |||
| d15c4c81b8 | |||
| cf500aba28 | |||
| 629eb18529 | |||
| 59cd4916ee | |||
| 673fa12d4a | |||
| 9b329c6c92 | |||
| 86318adc5c | |||
| 44f5cc8467 | |||
| 552d07af03 | |||
| 74a3d1f4ae | |||
| a9586eba1d | |||
| 33dafbd085 | |||
| c0daacc6dc | |||
| 7423eb63f1 | |||
| 1459a3aa53 | |||
| ec09fa2607 | |||
| a24940a095 | |||
| e08c279a50 | |||
| be1e9f6b2c | |||
| 822cdb4f85 | |||
| c7a4cb28d5 | |||
| 5e03dfb398 | |||
| aa9f0dc1d9 | |||
| 154cbab69a | |||
| 14c5a5b9df | |||
| 530dff515b | |||
| 057c6c20e8 | |||
| 5f2f390cb9 | |||
| bf91c8e9a2 | |||
| 72a62b4772 | |||
| 885f064b61 | |||
| 50c42997cf | |||
| f3b2e9fe69 | |||
| 5f7fa8ee2a | |||
| c957ccca57 | |||
| d2ed47410d | |||
| 06237977a1 | |||
| 55459bc112 | |||
| bf3fc9ff78 | |||
| cb73854822 | |||
| b5e976adcf | |||
| 1c025c15da | |||
| 86af52a1be | |||
| 31543ef39a | |||
| aa8832d1b6 | |||
| 08a9ffcd90 | |||
| 912547bc26 | |||
| 892b82104a | |||
| d414125098 | |||
| fb3fb774fa | |||
| 2c3804d321 | |||
| 1965691612 | |||
| 2e2de24368 | |||
| d4544bec17 | |||
| 35628a3e2c | |||
| 9944cbb0a7 | |||
| 6631c516f8 | |||
| a22f0ec65e | |||
| dee5033c0a | |||
| e11cbbc88f | |||
| 0ce1d8991d | |||
| 1c49f0319e | |||
| 55c321b678 | |||
| dcae514215 | |||
| 563e5a704c | |||
| 7e0eadb254 | |||
| 93667e2f46 | |||
| 27c5b2d589 | |||
| 148e1449d1 | |||
| 3cf539d90e | |||
| 9cbb2b0166 | |||
| ddd3b91d28 | |||
| fbf821c714 | |||
| 6313f50433 | |||
| ed897f0615 | |||
| 91e8f3c571 | |||
| b8503f190e | |||
| 3d569bf02e | |||
| 37b55759f2 | |||
| f7da64165d | |||
| 9b63c41c2a | |||
| 5ee2f4b732 | |||
| b9feb9602c | |||
| feb1a8325d | |||
| dc53c4f0dc | |||
| 298152a899 | |||
| f26c3a2349 | |||
| 2c87f68022 | |||
| 971b993a52 | |||
| 5c12922510 | |||
| da82fd3a16 | |||
| b606b91272 | |||
| 2624bcadec | |||
| 13a9b69d6d | |||
| 7a56b89beb | |||
| bc6561eeb5 | |||
| 959022fa07 | |||
| 8002559603 | |||
| f545369922 | |||
| 3600354ab7 | |||
| 86cbd17b42 | |||
| 5e6b864fdf | |||
| 9b89c3d815 | |||
| f9bddffc3e | |||
| e4a44c3663 | |||
| e7ff92136a | |||
| eb5ac2dac1 | |||
| 9ab56b1606 | |||
| 5fdff4c671 | |||
| 43ceac124a | |||
| 08b86b102b | |||
| b85e007b85 | |||
| 938d7144c5 | |||
| 2217826e56 | |||
| c920aff4c7 | |||
| da1bf30532 | |||
| 626d984054 | |||
| 9459c393df | |||
| 41388a4a7e | |||
| 8894f82477 | |||
| 560b5d8165 | |||
| 83d19d183d | |||
| e823d1d3ca | |||
| 5ea97d22a7 | |||
| 890387e6f4 | |||
| da0f824da9 | |||
| dad36dff47 | |||
| 3f885e7040 | |||
| f2cad36147 | |||
| ac24978984 | |||
| 2439399c08 | |||
| 19bdfec0b9 | |||
| ca8b96df32 | |||
| ab27481094 | |||
| c0c6e8aebc | |||
| cb220b6c94 | |||
| f802658d10 | |||
| 39b29ad284 | |||
| 3e0bbaa2f0 | |||
| 9f6e029e59 | |||
| 519e7221da | |||
| bda8f3910b | |||
| 88028d1da2 | |||
| 3d5354dd79 | |||
| 71d711902f | |||
| c6c66bb44a | |||
| 560e19e880 | |||
| 719ed77457 | |||
| 150f3e1e64 | |||
| 639e36f0eb | |||
| 1c343badcd | |||
| a87944ef44 | |||
| 12e9171e7d | |||
| 63f7510ebd | |||
| 93790772ae | |||
| 6b1b4f2448 | |||
| ba56d99e8b | |||
| c2e3b5a038 | |||
| 9808c57f1e | |||
| 33193806ed | |||
| 7d127738ca | |||
| 8386c25037 | |||
| e02718bc76 | |||
| f356c7d287 | |||
| 36987228f9 | |||
| 32b7bb9679 | |||
| b50559accd | |||
| 0f9c9b946f | |||
| 5f7468958f | |||
| 67213c247e | |||
| f79ae2f3ae | |||
| bb48a885d4 | |||
| 426e5d766b | |||
| 1c743429ae | |||
| ea3751aca8 | |||
| ead0f15e46 | |||
| 2d85ced5dd | |||
| 0ed6a0c8f3 | |||
| be46250dff | |||
| f60df79b15 | |||
| b5148f0fbd | |||
| d065179034 | |||
| 95e2cab689 | |||
| c0047ebf97 | |||
| 6fe42449dd | |||
| 6bd322e195 | |||
| f06da2f6ac | |||
| 632831a76e | |||
| f5693b0b86 | |||
| 3079caf246 | |||
| 9d4b7d27ed | |||
| 413ec650ed | |||
| 6f9484421e | |||
| a6661af96a | |||
| 60e15aaaac | |||
| f0a2781682 | |||
| d3235763dc | |||
| 41ff9b4579 | |||
| 99602c4add | |||
| faccabef47 | |||
| 344c588844 | |||
| 6886e38103 | |||
| cbcb4ef59a | |||
| 47b768b7d7 | |||
| 7f24732078 | |||
| 7b21150c10 | |||
| 48f820cc33 | |||
| faae572342 | |||
| 992dcbd0c9 | |||
| 3acdd9403c | |||
| 990aab5f5d | |||
| 50344b19c0 | |||
| d0d78f3450 | |||
| a25a662a02 | |||
| c38eb784aa | |||
| 7e15a61ed7 | |||
| becf99ad1f | |||
| b515c7f050 | |||
| 9fea866da9 | |||
| bbf1456fd8 | |||
| 20cf96e969 | |||
| a611ea24b5 | |||
| d633a62bdc | |||
| 4b3b005833 | |||
| 433da491d1 | |||
| 96174ea80e | |||
| 5aae04915c | |||
| a915981b6a | |||
| 35c3541d70 | |||
| 38f9eaf312 | |||
| 3f18352bdc | |||
| 2c57def881 | |||
| 2d50bdd375 | |||
| 91ffa16e17 | |||
| 6dd5b4aa6b | |||
| 1bce7ec7ec | |||
| 39d5ceaa03 | |||
| eef94a8048 | |||
| 5e5cc1e426 | |||
| 4471b1ac32 | |||
| 93d117b45d | |||
| 1b37e41e00 | |||
| 71e4a6c1a9 | |||
| d1881e474f | |||
| 0d43f5dea7 | |||
| ffb1a0769a | |||
| e7e8f19d02 | |||
| 3660a2f116 | |||
| aa10266c05 | |||
| bd100c1f4f | |||
| 1fcdf783e5 | |||
| 6d6570e92c | |||
| 917fb303f2 | |||
| 0e41248edd | |||
| 795575a074 | |||
| ecf7ad1ad2 | |||
| 66d0825a67 | |||
| dab92bdca6 | |||
| ca530221eb | |||
| 479efe7e7d | |||
| ad8606c782 | |||
| c291c5166d | |||
| a8b4f05de2 | |||
| 3c21bfb9f4 | |||
| 27265c533e | |||
| 0e431e2984 | |||
| 3b4410c9d9 | |||
| c46d07cde5 | |||
| 1375d12a08 | |||
| 26088f8ba5 | |||
| ab99abcbae | |||
| 4e4972d440 | |||
| 78b83266e3 | |||
| c6f4da1c04 | |||
| 62026e5ba3 | |||
| 4c965bd2d5 | |||
| 14ce11c778 | |||
| 13c9b4b74d | |||
| 4437e01af7 | |||
| 92641323db | |||
| 36a36c38cd | |||
| 0e008d0885 | |||
| e8bae220e6 | |||
| f96f0da3f8 | |||
| e6320100e8 | |||
| 8401827afb | |||
| ae6d69a173 | |||
| 391823d677 | |||
| 9388618ac5 | |||
| 2f1455d53b | |||
| ed6b4e4c6a | |||
| ac1d4a7076 | |||
| 99d354224e | |||
| 7474f785e5 | |||
| 4df73e1e61 | |||
| 69fc1a5b73 | |||
| 734217e0da | |||
| b4f015e4c0 | |||
| e8a2900beb | |||
| 922e77e4a6 | |||
| edb88c3f57 | |||
| 38204c4053 | |||
| b8e60cd7ef | |||
| 13d8f5fd7c | |||
| 6c06651759 | |||
| eb07593088 | |||
| b8faaba829 | |||
| 8726770c03 | |||
| 7d267fa13d | |||
| d1d95aa643 | |||
| 694b446e1a | |||
| 05817056e5 | |||
| dad4e4cfc9 | |||
| d85334ced7 | |||
| d0b65f2638 | |||
| 8753c9c931 | |||
| 77df5f6129 | |||
| 95a901d653 | |||
| f1595837df | |||
| 2c5c3eddbf | |||
| a7fdf52eaf | |||
| 1100364efd | |||
| d4fb7207aa | |||
| 6f0a9b7123 | |||
| dd83225447 | |||
| a6b20ad398 | |||
| 02d2fff162 | |||
| ac8407cd19 | |||
| f1348373cb | |||
| 1b80ba69a1 | |||
| 3b3018b173 | |||
| 09400814d2 | |||
| 3bde48937f | |||
| f4ec48675b | |||
| c61cf9d10a | |||
| 7d8a9de746 | |||
| a815b217b8 | |||
| 0413a838d3 | |||
| 542917efea | |||
| 08f9580b54 | |||
| 26673810ec | |||
| ccbfcf2e66 | |||
| c49324eeff | |||
| 7223456b53 | |||
| 9ce0033c88 | |||
| 4daffd0294 | |||
| 7cb385c35c | |||
| 52fd0d331b | |||
| 5f7602cd79 | |||
| 33ee2d7217 | |||
| bc792926ae | |||
| 34e4341ab0 | |||
| 744a0fc32a | |||
| 2307e892a9 | |||
| 38f01b02a6 | |||
| b9be5eae5e | |||
| 0ef5a689f9 | |||
| d99dc6846b | |||
| d13cb056f0 | |||
| 2475f952df | |||
| 055d6cdcd7 | |||
| a3cb5e253c | |||
| 7b5ef26e7e | |||
| 9c061a77ae | |||
| e4a0830ad1 | |||
| 06880647b7 | |||
| 918bd8f34e | |||
| 99c1f4c87c | |||
| 4efba7e295 | |||
| 744d93b938 | |||
| 17ebe08e52 | |||
| f7b57643ef | |||
| 9a4b87626a | |||
| cfaad3b04c | |||
| 1517302940 | |||
| 82d3165a19 | |||
| 03689cdd77 | |||
| d355f82de2 | |||
| ea5295cdb3 | |||
| dfd0261cda | |||
| c73f21ce0d | |||
| 5e0c4c074e | |||
| 919674e25a | |||
| 976c0018e9 | |||
| 10d26f6fbf | |||
| 631bc150ac | |||
| 2ae6bcc5dd | |||
| efbfb2b320 | |||
| f89b34f2b0 | |||
| 063b753892 | |||
| f704df9365 | |||
| a04a2de5c5 | |||
| 6b8f893299 | |||
| 49ce068117 | |||
| b6b6dfe01a | |||
| 9e7fbdf6bf | |||
| 041994aa58 | |||
| ed1fb3c8a3 | |||
| fa500b947c | |||
| 7c8ac6822e | |||
| 6489cf7bf8 | |||
| a17bc9bf9d | |||
| 5660f461e0 | |||
| 6b5017f016 | |||
| a42a7a8f00 | |||
| e34007c1b7 | |||
| 2fc551ac99 | |||
| 6a8f3a44c0 | |||
| 847ef6c6a6 | |||
| ce724611d5 | |||
| 178371eed6 | |||
| 3d92fb099f | |||
| 68be4a5f65 | |||
| 931a0f0b3b | |||
| fd113ae212 | |||
| 07ef076472 | |||
| a722390fbf | |||
| 6abc381aec | |||
| c69932eaae | |||
| d2e34d3bcf | |||
| 7bf373248b | |||
| 0d54063c5e | |||
| 31eba101f6 | |||
| 5ef157063c | |||
| 8ff7cdeddb | |||
| 58e59a9193 | |||
| 38c072c871 | |||
| c024b0fa97 | |||
| 1a72f3a8b8 | |||
| 76f87c5e08 | |||
| cb0ba6cf7e | |||
| 5fddf72bed | |||
| 795410a6c9 | |||
| 4f59ac109b | |||
| 408774cba3 | |||
| f509d042ab | |||
| 15977512dd | |||
| faae4b0533 | |||
| 8e26bd9711 | |||
| 4296b78333 | |||
| 44ea050a13 | |||
| 40609d803f | |||
| 1471ac699c | |||
| 9083aef7a0 | |||
| ab1230f5e1 | |||
| 0ec4723b46 | |||
| e7072aaf6e | |||
| 95cddcd6a2 | |||
| 6928a91060 | |||
| 9b3443dcd6 | |||
| 8c2ec8a565 | |||
| b3b76bfc35 | |||
| ee98b0c128 | |||
| 7f58cc1f5f | |||
| b1b9886f65 | |||
| 5bd45c66a0 | |||
| 470b1b376c | |||
| d29cbccf50 | |||
| f50a7de5a1 | |||
| b62a45397b | |||
| 67d75d9eba | |||
| 8ddf285340 | |||
| 544d0bf7b4 | |||
| 390ec689c2 | |||
| 78c7b11c36 | |||
| 5f8590054d | |||
| 29c8d09583 | |||
| cdacd7ca2e | |||
| 7bcc9e2e5a | |||
| a722036b8a | |||
| 1927da75c1 | |||
| cc60b9e32b | |||
| 79135a988d | |||
| 9ed9056ff1 | |||
| 52168ba071 | |||
| 6d5c24af2f | |||
| b02cb1a6bc | |||
| 98cc1649f1 | |||
| c81d957094 | |||
| bb83c2c7a1 | |||
| dc9c05ba8b | |||
| 3106a59fc4 | |||
| fcefdbece2 | |||
| 1ceae353bf | |||
| 64eeeaafc8 | |||
| 40b066a3b9 | |||
| af9cd2135d | |||
| 11c3758976 | |||
| 55f6786b2e | |||
| 50562d49a9 | |||
| 3ce74d7c57 | |||
| 750660c333 | |||
| 882589d5b0 | |||
| 93aed1b818 | |||
| d157084851 | |||
| 7e68fdd63e | |||
| ceed9b79b8 | |||
| 93d21a4c97 | |||
| 68b93fd1bc | |||
| e903534862 | |||
| 71af5ad8b1 | |||
| e3c027907f | |||
| 5d04730011 | |||
| f34134b215 | |||
| 4c00d5f5ae | |||
| cc0a590ec6 | |||
| 7497af7022 | |||
| 7f4dbb3e2e | |||
| 3ef2575788 | |||
| e01a754315 | |||
| ac7b024a38 | |||
| 413cb0a987 | |||
| 9b56a35f26 | |||
| 0a2e6964ca | |||
| 8a21ac8737 | |||
| a956c52e6b | |||
| 9248aae9a9 | |||
| dffe13e344 | |||
| a7d5d5a715 | |||
| 7e16db1b62 | |||
| b1fc0bf6bf | |||
| 013a50e87e | |||
| e41ef67f99 | |||
| 8b951cbc17 | |||
| 179f6a19d6 | |||
| 1e1305c24c | |||
| 8b08f066a5 | |||
| bf147efeec | |||
| b2f1b85900 | |||
| 6fbf05175e | |||
| f5bd331c3c | |||
| 7506932ff3 | |||
| 108d595edd | |||
| 5aa5b65662 | |||
| 3e281fe41a | |||
| 3d6b5b3a4a | |||
| fed19d9c02 | |||
| b70a4dd41c | |||
| ec3ebca433 | |||
| aa014cbe91 | |||
| 9c531401af | |||
| c1c71b3b64 | |||
| a5bd6563dd | |||
| a9505b4d2f | |||
| b3cfdb7126 | |||
| 57cf532863 | |||
| 1d32fe52f5 | |||
| caeec11624 | |||
| 1ca8c8fdf5 | |||
| c3b4fe53e9 | |||
| 627e400a02 | |||
| 38c19fc150 | |||
| 8d0b1b79be | |||
| d208452096 | |||
| 0c787fcbfe | |||
| 9bf64cccda | |||
| 79a565f4d9 | |||
| 94c3a75a96 | |||
| 7028149361 | |||
| 9fecaf1372 | |||
| 703d9f2ce0 | |||
| 70aea65078 | |||
| 35e0b73ada | |||
| 023e479beb | |||
| 0a471f2e56 | |||
| 6ec571a1b9 | |||
| 375653fc30 | |||
| 43855925da | |||
| b105285d88 | |||
| a3b877231f | |||
| a8a1880f0f | |||
| 0c40e05195 | |||
| 601b26ebfb | |||
| 39a3da9e8f | |||
| 718c4055a7 | |||
| 4f95851a4e | |||
| 1d76446890 | |||
| cfc893cd56 | |||
| bc43f5ecc5 | |||
| 230a4349d8 | |||
| 153b5b71ba | |||
| e6456b022f | |||
| 03e6e332c2 | |||
| 65814d625c | |||
| a85e25da74 | |||
| d79d7255aa | |||
| b169972f72 | |||
| 91621b5393 | |||
| 6e6a5fc4e4 | |||
| a9b8c9dd02 | |||
| 49319139e0 | |||
| 3b547687f9 | |||
| 77b10f6c27 | |||
| 8ee296529a | |||
| dd013f3a70 | |||
| b48f49c444 | |||
| aa171353df | |||
| 98c7c0f215 | |||
| 855c13cb57 | |||
| fd8f4d5a16 | |||
| 585efd1eb2 | |||
| 6b25fb0482 | |||
| 5c961dd25e | |||
| 4e1a285119 | |||
| bbb9a86275 | |||
| 78b83125f4 | |||
| 6c038db4bb | |||
| f2deb4428c | |||
| 2bc390d9e3 | |||
| ab547d8cca | |||
| 1202d6899a | |||
| 74a8cb927a | |||
| 5abd33d9dc | |||
| 821809c994 | |||
| 1d6466249f | |||
| ce56d05d5d | |||
| ac22fec171 | |||
| 8c6b27aedb | |||
| e5b112504a | |||
| bbd419d69c | |||
| 8628ea8030 | |||
| fcfec701d0 | |||
| 04bc1cd02f | |||
| a01c031331 | |||
| feb671ca7c | |||
| 0a9c821500 | |||
| 66f71b4bbb | |||
| d7061e154a | |||
| 9af2e54f6f | |||
| 00fa8ca383 | |||
| 493cb0a56c | |||
| 09bde1a85b | |||
| 30b75f16b4 | |||
| df92e08671 | |||
| b3eb11b9f0 | |||
| e64abba601 | |||
| 2392b99817 | |||
| f37e0db153 | |||
| 4f164cdb55 | |||
| 1f63b68908 | |||
| 283c9b5922 | |||
| 35b4a9f498 | |||
| d36fca5a1e | |||
| 3d7765f066 | |||
| 7fe805cd48 | |||
| 6735dc79fb | |||
| ccd0150df3 | |||
| 0289fea89a | |||
| 3b23f6b13d | |||
| 03a25aab88 | |||
| 756c47980d | |||
| 4e923e1aeb | |||
| 775aac53b5 | |||
| f932be684f | |||
| fa5af4a1ec | |||
| a6f0e97ed3 | |||
| 3873826036 | |||
| 580de6574e | |||
| 7af68d6d9f | |||
| 0986ba8497 | |||
| c8eca17adc | |||
| b55689ebf4 | |||
| c731c371d3 | |||
| 98e2d2fd7c | |||
| b6fe9892c7 | |||
| 0f36373920 | |||
| 428ef88fce | |||
| 62ba209e52 | |||
| 36025ee6ba | |||
| 75a95382a4 | |||
| 82a0d1f4bb | |||
| 8723224548 | |||
| 3135239602 | |||
| 06019c095b | |||
| 3a2f3045e5 | |||
| 82f7bb99f8 | |||
| ee3ea72208 | |||
| 7b5c123071 | |||
| 731443616f | |||
| 94f1198fe3 | |||
| 7a9d867fd1 | |||
| 21107efaf5 | |||
| 53d967abce | |||
| b41b71169f | |||
| 2d2d3822d7 | |||
| 2dcee8eae1 | |||
| 1109ff8160 | |||
| aaa4094cdd | |||
| 209f3ec710 | |||
| 22ba423e36 | |||
| ba1c0e4a7b | |||
| 0864958ac8 | |||
| 5389fcb030 | |||
| 9011d62bf4 | |||
| f20ef8cc67 | |||
| 9aaec5e69c | |||
| da11f3829a | |||
| 0fc19d9959 | |||
| ab2d01ad0c | |||
| 0ef32f9df4 | |||
| 082fe28cc8 | |||
| 31e3099c7c | |||
| 29649a7d79 | |||
| e81f3e5959 | |||
| 6eea1e55da | |||
| b512c16c7d | |||
| c31bd24494 | |||
| d1f3612825 | |||
| 4440a2d44a | |||
| 60556207bf | |||
| 28885e75a1 | |||
| 9dd5b9762b | |||
| 149e6aa9a7 | |||
| c7df199a2f | |||
| 8151645882 | |||
| daa3afe812 | |||
| ec864e6b71 | |||
| d858fc8eb3 | |||
| 0f1e93ab7d | |||
| 80cfa7e736 | |||
| 0c80e7afaf | |||
| 82b2f2f8fe | |||
| 205bc5f65c | |||
| d82ed41f65 | |||
| 36b99d5651 | |||
| 867b92a6ea | |||
| f88617ab05 | |||
| b936b00df7 | |||
| 31925a9c85 | |||
| 1b7332dea4 | |||
| 78f0196571 | |||
| c425f20994 | |||
| bd6fd1d103 | |||
| 3ebc962a71 | |||
| af21acc641 | |||
| 4ffa307bc5 | |||
| d1d26af5ee | |||
| 5ddfdf7dc3 | |||
| db8a289ff8 | |||
| d0de74737e | |||
| 5f2c8eb9dd | |||
| 9e14904eb2 | |||
| c4ba5f8da8 | |||
| 67eca005d9 | |||
| 105f96a4d7 | |||
| 5fa25b65f4 | |||
| 1b11b31a18 | |||
| 3146238b35 | |||
| 915c5f6531 | |||
| 0b1aeddc31 | |||
| 609515a4d8 | |||
| dc98c93c02 | |||
| ebb1fb41d4 | |||
| f7520a9195 | |||
| 5257b95dbd | |||
| 54f926a946 | |||
| 5894ac7f4f | |||
| 419310c4f7 | |||
| eadc5bc027 | |||
| 1e8d3a58e4 | |||
| 42ca45db68 | |||
| 252970c2e5 | |||
| 87459991a9 | |||
| ca84b8b85d | |||
| 1fb8c54efb | |||
| 474953daa5 | |||
| e303d7433d | |||
| 1c7262b1d8 | |||
| 76c554227c | |||
| 4b41477379 | |||
| 243321d442 | |||
| 28d75a78e5 | |||
| 081fff5e0a | |||
| 5a00738390 | |||
| 11a5c60ecf | |||
| 7c138b2f77 | |||
| e056d9b1a7 | |||
| 3d53184985 | |||
| 1e9319b239 | |||
| 8a4fbce55b | |||
| 14e6ae0cdf | |||
| e2102f6e1e | |||
| ca208da2fb | |||
| de99ef67e6 | |||
| d62498a099 | |||
| 4b17cf9b6f | |||
| 1dd627c9c3 | |||
| 5267970499 | |||
| bb7ca06680 | |||
| 157c498e79 | |||
| 3e79c6d06b | |||
| 74e699e560 | |||
| 1f8dc86e76 | |||
| df906a343f | |||
| 82aa3db9ff | |||
| 19b8cd81eb | |||
| 2489a45e18 | |||
| 0ac1a2f9ce | |||
| 294dc041c6 | |||
| f811b3f6bb | |||
| f8407848c1 | |||
| 2384f56ec0 | |||
| d0e74392fe | |||
| e51dae3b9f | |||
| 38e95423b8 | |||
| ae00227275 | |||
| b0c407d4c3 | |||
| e26e98dbba | |||
| 6772775696 | |||
| 168cb146ea | |||
| f1343f95f1 | |||
| a5ca5718b4 | |||
| 83ddeca71a | |||
| 5b2f73f74b | |||
| e63be19fe5 | |||
| d9211d2c40 | |||
| c57a1b4da3 | |||
| edfe606cc3 | |||
| 1afd639b6a | |||
| e1126e464e | |||
| 02d8ddfe42 | |||
| 279126262b | |||
| bb0f599a2f | |||
| 14faae9c6d | |||
| 51fc20c96f | |||
| 526e1d2869 | |||
| 17aae92f7f | |||
| 1b06ae8c30 | |||
| 2b71d7f814 | |||
| 532f5c9c37 | |||
| 398fefa919 | |||
| 7bdb4d7c6c | |||
| 266f8dd3a8 | |||
| 19388f063c | |||
| bfc333624d | |||
| c9e9d93f92 | |||
| 55f10e2a09 | |||
| bbf358f161 | |||
| 068767c80d | |||
| 827248cc74 | |||
| d9835634b8 | |||
| 8a4467a33c | |||
| c5708f746c | |||
| e72aa19280 | |||
| 731b044d50 | |||
| f744ef7464 | |||
| 21dee86554 | |||
| ffb7d19497 | |||
| 8994711cd4 | |||
| 8e1081e8b6 | |||
| eeba0187bc | |||
| 64f64bd139 | |||
| 1b98d3c25c | |||
| b2bcd08c99 | |||
| fac1558de3 | |||
| b5fafaada2 | |||
| d1bf5f628b | |||
| a6993eae9e | |||
| 379b9255b2 | |||
| e8867012cd | |||
| 0a275a74de | |||
| 2e060c3e5f | |||
| 14c519fa1c | |||
| a4ed49d510 | |||
| 5149eaab2a | |||
| 210e694e6c | |||
| 9aef3bc41a | |||
| 5fed774201 | |||
| 9a00e7cba9 | |||
| 3f63746052 | |||
| 1f17c35656 | |||
| 62a32c08be | |||
| 8f42e2346c | |||
| 94881ba4c0 | |||
| ebe9695cc6 | |||
| 95dffd86e7 | |||
| a8e372ebef | |||
| 60136d89b4 | |||
| 952a842509 | |||
| bf3628f33a | |||
| fde5cbc313 | |||
| d767fe7f12 | |||
| 7f622c7401 | |||
| 8bb91a070e | |||
| d277684331 | |||
| d7a63f2277 | |||
| 3dd430026b | |||
| efcb30ed69 | |||
| 96b68f0dba | |||
| fcee7086eb | |||
| 13253957ec | |||
| bc17eec490 | |||
| 625458ecda | |||
| 1a829d5273 | |||
| 2a3d80ac18 | |||
| 71c986ed29 | |||
| 5d99bd934e | |||
| fb100aaa79 | |||
| a4ec72dbd4 | |||
| 8f3b3fabaa | |||
| 4f719c7c7e | |||
| 02a07a59d9 | |||
| 078bf9a18a | |||
| cf284194f2 | |||
| cba3d9acdb | |||
| 7cfac8b59c | |||
| 65df50346a | |||
| b92cf09eb2 | |||
| 175e73202a | |||
| 43a2225778 | |||
| 7811150fe5 | |||
| 7a94df491a | |||
| f6ba7f0e0e | |||
| b4347bd901 | |||
| 697aef6be6 | |||
| 58e8752e45 | |||
| 096e4e917b | |||
| aa08d8c7ae | |||
| d80a8334c8 | |||
| 0614fcdf51 | |||
| ce2a679a3c | |||
| 0765354589 | |||
| 9d3d04a00c | |||
| 2ab6c09339 | |||
| 532a126289 | |||
| be5c39e50a | |||
| b2b11a6ffd | |||
| b66618093a | |||
| 3d5059e882 | |||
| 145ced3ea9 | |||
| ce83b03fc7 | |||
| 26d4b32987 | |||
| eaa8a29d2d | |||
| 67de70303e | |||
| 8bc65c5320 | |||
| 2f079c3ca4 | |||
| 2f566a3c25 | |||
| 41c4c7ec37 | |||
| 32f77551ae | |||
| c261027930 | |||
| f87121f42d | |||
| 070fdb7275 | |||
| cecf41cb20 | |||
| 8091a4fc34 | |||
| 47ca296b66 | |||
| a245a28c4b | |||
| f7a7dc61d3 | |||
| 2f5daac8b2 | |||
| 67c3f8fcc4 | |||
| 1fdec50702 | |||
| 0d23cb0d30 | |||
| 7c3e390c04 | |||
| 36aee4324c | |||
| 1385341bc8 | |||
| 8a188747ae | |||
| adcb2f3e87 | |||
| 5e40d76375 | |||
| d8425e7bd9 | |||
| e3c113f11d | |||
| fda91f045d | |||
| 99eb79957e | |||
| a683f775ce | |||
| 399261b643 | |||
| ce79ed9657 | |||
| f2cf17804b | |||
| 4c95630c4c | |||
| ce9ac484d9 | |||
| edaf7e9d6f | |||
| 49181fb06d | |||
| 3c3369f64b | |||
| 765e232693 | |||
| 35b40c4434 | |||
| 17e0f159b0 | |||
| 1d95cf19f0 | |||
| c3f21c4a95 | |||
| a7ad3dd8e8 | |||
| ea317649ac | |||
| c2f788c69b | |||
| 6d3404c763 | |||
| 52a24d511e | |||
| 9ef4523f47 | |||
| 37dfa061c4 | |||
| 9a989dddb3 | |||
| ae2ff8a3b2 | |||
| 80a34b036d | |||
| f2e39bf9be | |||
| 5f2339d105 | |||
| f5b4355a9a | |||
| 0bc97cbc88 | |||
| 3bd03b0129 | |||
| 67a0b93456 | |||
| 1d66235e57 | |||
| d653ccd38b | |||
| d30b62ad0a | |||
| b7b3415e9a | |||
| 22cc0ce643 | |||
| 5bec2323ac | |||
| 95b5764edf | |||
| 08fe4a0c96 | |||
| 06f6a164f1 | |||
| a654b13a9a | |||
| f0b7d6631b | |||
| 01b390fcb7 | |||
| 727a49fb46 | |||
| e9f55cc418 | |||
| dc87322f43 | |||
| 6560136ec4 | |||
| 6a70625563 | |||
| fca08c03bf | |||
| f572ff84ea | |||
| cbe07715fd | |||
| 01a93d5488 | |||
| fd2f4ea5bf | |||
| f7dd8ba630 | |||
| 748cf0b8b1 | |||
| 64a9f4fef7 | |||
| 265608196d | |||
| b4b6f98d1f | |||
| da64502850 | |||
| 93158337c1 | |||
| f1a6e22cb6 | |||
| 342d8676bf | |||
| 6aa0f69ce0 | |||
| 318bd7a92d | |||
| d62bb7a516 | |||
| f44424a75a | |||
| c2a2058fcf | |||
| 02a6a45796 | |||
| 5798ca100f | |||
| 487f71bd0b | |||
| 99caf8d74e | |||
| b79cf1b9b4 | |||
| 8a58c5eb1a | |||
| e1aac9cc13 | |||
| 0dd6014135 | |||
| dbaf23ed69 | |||
| 45986fb2da | |||
| 637a75f0fc | |||
| a52e05598b | |||
| f32de44b19 | |||
| 04372a3738 | |||
| 6906e2cac4 | |||
| 7818fb1c96 | |||
| 96e7ad74c9 | |||
| 664ed5c7aa | |||
| d139cc3fb1 | |||
| 8ce7457f3f | |||
| 0a9b5f4f0a | |||
| 850652f527 | |||
| 6bba09cbf2 | |||
| 891792b987 | |||
| c8ccc5c9bd | |||
| a57a39082b | |||
| 8da2368e26 | |||
| 6987468364 | |||
| 566d8606d0 | |||
| 02d4df2a02 | |||
| 143cb1de21 | |||
| 06f65b44b3 | |||
| 325d3be574 | |||
| c7162adf31 | |||
| 2af76d2e69 | |||
| 7a8b5e755f | |||
| 0dfdb3af4e | |||
| be3d4d1d74 | |||
| 33ff9c1f7c | |||
| 347311e78d | |||
| 0044e210ae | |||
| 606764fc9e | |||
| b2fa981e36 | |||
| e62eb56f4a | |||
| 43a8bb9a39 | |||
| d6857176d8 | |||
| 574ab0a834 | |||
| 8e5ec60e2d | |||
| 4de8ff7269 | |||
| faa0781c8b | |||
| 38f71856a2 | |||
| 91ff747733 | |||
| 41734c682e | |||
| d7144c0a24 | |||
| 2b2ed7551d | |||
| a6470864fb | |||
| a2021c2704 | |||
| 1331f5b634 | |||
| a7c7d1426e | |||
| bc0549397a | |||
| 5894a82ced | |||
| 11853c6f5b | |||
| cdeb113846 | |||
| 97b847314b | |||
| 6cb397247f | |||
| a658e20b27 | |||
| f5837b5245 | |||
| 45ad808d0d | |||
| d847b85c7a | |||
| 4927f38429 | |||
| 294fef724b | |||
| 6413493e9d | |||
| 393bbd547c | |||
| 60657014ea | |||
| daf199c520 | |||
| 451601348a | |||
| e8447d24ac | |||
| 2a8225ddeb | |||
| b0cbdd8ba7 | |||
| e1789dcc81 | |||
| c47bd93bb2 | |||
| 886a027c6b | |||
| a9774d3920 | |||
| 391882fbf6 | |||
| bb33238efc | |||
| 2113c1308c | |||
| dc6a5fce29 | |||
| ad98a01899 | |||
| 0fa8720145 | |||
| 0feb4c18c2 | |||
| 3472e11ef8 | |||
| 1b4c33da51 | |||
| 331f2c441a | |||
| 0933bf3682 | |||
| d882a94368 | |||
| a96a8184a2 | |||
| a3c03d139a | |||
| 9ad88fece8 | |||
| 44a9f8491d | |||
| b528c2e57c | |||
| 37e40e4a0d | |||
| 0861cbbd80 | |||
| 43b46ceccb | |||
| 1f3a6348b0 | |||
| 0b4379b06d | |||
| a7e100888b | |||
| 357285a579 | |||
| 6447659882 | |||
| 3df663e0fe | |||
| 35625c3f81 | |||
| 97dc035bcc | |||
| 2d51cdae66 | |||
| f166322976 | |||
| e5addc8965 | |||
| 8267989279 | |||
| a8d7c8a9c4 | |||
| d4d3515c8a | |||
| f40546b1f5 | |||
| a41b66ae8f | |||
| 4d8eab61cb | |||
| 76c49a67dd | |||
| af0115d4f5 | |||
| cb09463326 | |||
| 26df96b886 | |||
| 4e9c666886 | |||
| 8bcfa19259 | |||
| 9944effb93 | |||
| 8d72e632cc | |||
| 566359a20f | |||
| e3a126af54 | |||
| bc6f48e1b6 | |||
| 885150daac | |||
| e404792c29 | |||
| 3d38d0be9f | |||
| 43146eac1f | |||
| 3997e7fa65 | |||
| 5a77d39355 | |||
| d348235050 | |||
| 4617ed15a9 | |||
| e7d3488ea6 | |||
| 23d1a51134 | |||
| cb5c5fc67c | |||
| 6fdef21374 | |||
| 32be9063b8 | |||
| 8b3c8024a7 | |||
| e4a8a2662b | |||
| 14aad65c0c | |||
| 0e07a54085 | |||
| 60797bddca | |||
| ca4a0c37e8 | |||
| d02fea28ea | |||
| d1e79a7d7a | |||
| 19bebc50de | |||
| 78ee899da0 | |||
| df283db810 | |||
| dcc02f75c3 | |||
| 328a77bd03 | |||
| 0c7bf67e99 | |||
| f79a258c80 | |||
| 4dc037bac8 | |||
| e1d403057b | |||
| 2e886e9405 | |||
| cff869e33c | |||
| 9943db95a3 | |||
| d4e47e9dd6 | |||
| da69d6cd2e | |||
| 00d97e59b3 | |||
| 6a9bdd0c6a | |||
| 9dd573f971 | |||
| bf9a58bdd4 | |||
| be832ceb4d | |||
| 5f565184c1 | |||
| d75de7f627 | |||
| b4e18b48f3 | |||
| 75d45f811f | |||
| c0e8922500 | |||
| 66deb345a2 | |||
| 1ab2389cdb | |||
| a009893522 | |||
| 6507fa5b1d | |||
| 121c796d48 | |||
| 88e5c9a1ba | |||
| af3c686111 | |||
| c980451725 | |||
| ed704a4dd7 | |||
| 0c22d50477 | |||
| 3cff5465d6 | |||
| 6d0106df22 | |||
| 7316e74b65 | |||
| 61ae46383e | |||
| f646621cc8 | |||
| 2911e71bc6 | |||
| 5b4146c967 | |||
| ae74401668 | |||
| 72a6e9473a | |||
| 7f72419e3c | |||
| ff9c31b88e | |||
| 615a1300ec | |||
| 6503b98e28 | |||
| ccd4fca695 | |||
| 75cba2cccd | |||
| ab3f3efceb | |||
| 992df72fac | |||
| ddadd81f4a | |||
| b2ca3ef066 | |||
| 5ae5329de8 | |||
| 251f61a039 | |||
| 486985f330 | |||
| d0d2b246e4 | |||
| c2c27470ff | |||
| 69e8f8e050 | |||
| 9255d01d6d | |||
| f2257718c6 | |||
| 5edc98545d | |||
| 5058866698 | |||
| 1a3f4d37be | |||
| 3e536dd4a8 | |||
| 85c20f7b4b | |||
| e4f3365414 | |||
| 8165bd59a4 | |||
| a89de7da1f | |||
| d566e54dfe | |||
| c9e0f26fd0 | |||
| 6573a64544 | |||
| 7fd2cab387 | |||
| a56b5382e1 | |||
| 9f59ab6081 | |||
| 5ce2f4aeff | |||
| e3d4841808 | |||
| f2e40a87d4 | |||
| 2ae8c3dca5 | |||
| 73bd4bb628 | |||
| a0333cfffc | |||
| 65d5cd5918 | |||
| 6b49f49ba0 | |||
| 5aebdf4119 | |||
| dfa7f535ab | |||
| e25a128bb7 | |||
| e1eb605394 | |||
| 0cd4115c25 | |||
| f37663053e | |||
| 1281376681 | |||
| 42ed0a0345 | |||
| 48750943db | |||
| 5ec7481030 | |||
| b543fae655 | |||
| f31800fad9 | |||
| f6295a2e4a | |||
| e5905d5b59 | |||
| 1e540cb6d0 | |||
| 09af30f24f | |||
| 4a317336fe | |||
| 4affeb3107 | |||
| d4341061e5 | |||
| fb544e8ad5 | |||
| db3ea84b02 | |||
| b8e3b08153 | |||
| 882efc32d1 | |||
| 0efea59a55 | |||
| 2598ceef51 | |||
| 88bb8e0920 | |||
| aad1ea6a01 | |||
| 0cd974fa6d | |||
| e1526d87b8 | |||
| 581bcfe066 | |||
| 2ed4d470b2 | |||
| ad6b1da130 | |||
| 09d946edea | |||
| f035629a35 | |||
| 279bbfe00c | |||
| 4a2c89f0d0 | |||
| fd7ae69b13 | |||
| 8e03cfb2cb | |||
| 2a88167957 | |||
| 49b855c55f | |||
| 97933a097c | |||
| efbe7a8fb3 | |||
| fb2abdbe1e | |||
| 05291b606d | |||
| efa9ffbd3a | |||
| b4b3541088 | |||
| 319231ecf4 | |||
| 4d144a10b1 | |||
| 5e0c752f37 | |||
| f23a9a0b7c | |||
| 2de81f9d1f | |||
| 25c8884db9 | |||
| 0ec5a237dd | |||
| 6bbbb6ac34 | |||
| 6c699fed35 | |||
| da173dc398 | |||
| b93a9b37ca | |||
| 5c3b2d3591 | |||
| 5344f90338 | |||
| 95506cff4f | |||
| 991266a50c | |||
| cc0c879538 | |||
| bd3a260096 | |||
| d8ebb6163a | |||
| 5dddaeb89d | |||
| 8c4f470d16 | |||
| 11b9c86ad0 | |||
| bccff56e74 | |||
| a74408c966 | |||
| 56679cf481 | |||
| f7662ab0a5 | |||
| ed3930edac | |||
| c9a4e980a1 | |||
| d4a2633699 | |||
| 6336fb0d2d | |||
| d8928959e3 | |||
| 6ec262af8d | |||
| 5a45794726 | |||
| 3b4dfac6f6 | |||
| 0a3d63ab01 | |||
| ec83606bf1 | |||
| c1df4145db | |||
| 0d3e8ff2ff | |||
| 4469e71cb5 | |||
| 22b6dadcbb | |||
| 56464c99f4 | |||
| 976cff1783 | |||
| f3926d247e | |||
| 7d5776f731 | |||
| 19dad1f586 | |||
| 63ba9b0431 | |||
| b6fa7eb1ef | |||
| f65fe67d86 | |||
| f48ef1c9c6 | |||
| 94df72ed99 | |||
| 80b4fa8a6e | |||
| 4d2801f6ae | |||
| 8d1db9572f | |||
| e00855f877 | |||
| 923f8e7497 | |||
| f26917ad37 | |||
| 2e61009a4c | |||
| fdbed20394 | |||
| 203fe955aa | |||
| e50879f5a3 | |||
| 8c1adf2189 | |||
| 119f64c25c | |||
| 2b88bc3fcd | |||
| 6d0bcb46ae | |||
| 00fd4ccebc | |||
| 06860070ab | |||
| 858066dc20 | |||
| 66b07aeb13 | |||
| 28067ea3e1 | |||
| 0f8ce8dba1 | |||
| 92b2486dab | |||
| 8c66b261d3 | |||
| 9348064432 | |||
| df09953d8e | |||
| 94a577bc72 | |||
| 7472400477 | |||
| 90af5ef06d | |||
| 6b55c264e5 | |||
| b5fe7e2a56 | |||
| bcf8ada78f | |||
| f84fe7b854 | |||
| 2b512ed4bf | |||
| 3bca687f19 | |||
| 440c023f42 | |||
| 223599f4e4 | |||
| 1559472ca3 | |||
| ad3301e932 | |||
| b2cba84ac0 | |||
| eb77dc369a | |||
| 883abd17d5 | |||
| 7a08431a58 | |||
| 0aaa44e063 | |||
| d7d89119e2 | |||
| d3b40684c1 | |||
| c7915f4387 | |||
| df19c361be | |||
| d9e682babd | |||
| c755f57c17 | |||
| 5a6b95d343 | |||
| 71ee300143 | |||
| 18dcec7bdd | |||
| 3656c654e9 | |||
| 1a489a91e8 | |||
| b2b415a5a0 | |||
| a3061f3ab5 | |||
| 0c82384137 | |||
| 7e55d8d183 | |||
| 76b3a1ae71 | |||
| 7f320909ff | |||
| dbe612e9dc | |||
| 53ea38aa3c | |||
| 88f69a298e | |||
| 6942bf541a | |||
| a0493aa6f0 | |||
| 60fef3d0e0 | |||
| d100d6cad7 | |||
| 7f55a93825 | |||
| 37d2e46a3d | |||
| 4619a22b97 | |||
| 397b5b5635 | |||
| 11a1eb8869 | |||
| 646b8f68b9 | |||
| e78fe1e233 | |||
| 2235c90136 | |||
| c0304a1a19 | |||
| 31301cd5f9 | |||
| 271550778f | |||
| 95ceae7711 | |||
| 79353bc30e | |||
| 744d339c9e | |||
| 4404f07691 | |||
| bf7e6ef42e | |||
| f3d2bab969 | |||
| e536ec678e | |||
| f779070199 | |||
| 2c31840fae | |||
| 2a3ae83eb2 | |||
| 6d7d2cd893 | |||
| 6da6a347fb | |||
| 15b0610051 | |||
| 024d0f8f16 | |||
| 3fb154355f | |||
| be56571256 | |||
| 54f166805e | |||
| 3889703ca7 | |||
| 536e85263a | |||
| e6aaa620ef | |||
| bb845fc267 | |||
| be1e58013b | |||
| 6578d99845 | |||
| 6da68ea87e | |||
| dba59f32ad | |||
| 68471a932d | |||
| b310936e45 | |||
| 245a8050db | |||
| 812c262b7e | |||
| edf31114c6 | |||
| 6f306c1622 | |||
| 1342d5408b | |||
| 82a62df7d5 | |||
| 7e061d8c8c | |||
| 166a811104 | |||
| 500d650ad0 | |||
| ae524435cc | |||
| b0684cb748 | |||
| 8361a9648b | |||
| bcbd5ba880 | |||
| 2ee9b482c3 | |||
| 4679447591 | |||
| ff19028f87 | |||
| 57e55c99ec | |||
| f9d059e706 | |||
| ecc0bbd5d4 | |||
| 8a890f15f5 | |||
| 19042479fb | |||
| a083033a73 | |||
| ece2db5782 | |||
| bc810ca90c | |||
| d970d06624 | |||
| c3123d70d8 | |||
| bf39d5d017 | |||
| 49a35624c8 | |||
| 4d993012d7 | |||
| c0c5cf747a | |||
| 6340e21614 | |||
| ae8230ebda | |||
| 78dd515f7d | |||
| c90142080f | |||
| baa7d04860 | |||
| 546e7c9ee6 | |||
| a66aa90424 | |||
| 2ea415976e | |||
| 9aebc99eac | |||
| 8784c81abe | |||
| 1618471dad | |||
| efd4d723fc | |||
| af2c7efa21 | |||
| 5d5faddaa2 | |||
| 3a0c0ec158 | |||
| 449367c7aa | |||
| 7544348e08 | |||
| 5193d4a785 | |||
| 253b871aec | |||
| d14085f3c7 | |||
| 3b90cddfff | |||
| e03e95b33a | |||
| 7214c413c8 | |||
| ebd361c201 | |||
| 6368a992f9 | |||
| 69e0cbe1b9 | |||
| 8731a1965c | |||
| c132415bc1 | |||
| 469c8391d1 | |||
| 01c871ff1a | |||
| 51ca1d36f2 | |||
| 44885ea0f0 | |||
| bd4daed2b7 | |||
| 85c5cc4d82 | |||
| 26b883cb69 | |||
| 5984d26a57 | |||
| 4580ba65e2 | |||
| 567e6dc74d | |||
| 49a8c07ad5 | |||
| db60c3be04 | |||
| 78a655911b | |||
| 5daf91c241 | |||
| 8798001270 | |||
| d8d9785173 | |||
| 4694a70b18 | |||
| d2d64120ef | |||
| d99d68c9da | |||
| d6053157ed | |||
| ade29fcc75 | |||
| b49a592c50 | |||
| a9f33abfe2 | |||
| 798c86e5ff | |||
| 4903f33300 | |||
| 02ec1aeb14 | |||
| 545e3224aa | |||
| 3faac482cb | |||
| 4e33b815b4 | |||
| 20fbdadcf8 | |||
| c1b833bd5e | |||
| 438237f3bd | |||
| 8a24cd47eb | |||
| fb41727385 | |||
| 635a39a772 | |||
| d516548532 | |||
| 5da4f5cc35 | |||
| 54f6ff4ea7 | |||
| f8dae595af | |||
| ec95c94bef | |||
| f3488ff27c | |||
| 5360662e2c | |||
| 5385f750d9 | |||
| 65941106a8 | |||
| e26b25e056 | |||
| 4133b81e38 | |||
| 92397e18a1 | |||
| bae2352a34 | |||
| 26150099de | |||
| dc1b31dac7 | |||
| 853d3847d2 | |||
| accc5f3341 | |||
| 8056f384d2 | |||
| 288f72aa85 | |||
| bce5c7d2e9 | |||
| a516480aac | |||
| a9e94e9569 | |||
| 96e2c8bc3c | |||
| 4d79c89f0e | |||
| b7792bab2b | |||
| 6998d1eed1 | |||
| 1f9ed0fa2a | |||
| 78044113aa | |||
| 87a68af4c3 | |||
| 7288ffdef8 | |||
| bd8c2bbda0 | |||
| f11169d396 | |||
| a81cf60f79 | |||
| 13c3630ff6 | |||
| af251553df | |||
| 00a32476f9 | |||
| bfea00fba4 | |||
| 15a05c8d7c | |||
| c810542654 | |||
| aff47d1d48 | |||
| db2f7ce63e | |||
| 8397b08b88 | |||
| ca61181daa | |||
| 9ccb4c6edd | |||
| 128d85c9a2 | |||
| 8a259eb2ab | |||
| 37403920a2 | |||
| 4fcc7dc1f6 | |||
| 3dd1a40f58 | |||
| 68712333e1 | |||
| a036248d63 | |||
| 48993971f2 | |||
| f574fe1a87 | |||
| 0f51f5ec4d | |||
| a94b4a618a | |||
| 912889fccc | |||
| ae8c7768ec | |||
| 082f4b729c | |||
| 312c886d62 | |||
| fb81d6a121 | |||
| 370f30a269 | |||
| d3d557de91 | |||
| 46e7bcf40d | |||
| a6ac1daff3 | |||
| 94c4f32b08 | |||
| ffd034811d | |||
| 9adcfecc38 | |||
| 802c1dc18e | |||
| 3ba8bdc854 | |||
| 7d8fdc7db6 | |||
| 7be050e1e2 | |||
| 706ffbe594 | |||
| 878cb2befa | |||
| 1f10d4bc4e | |||
| 475fadf31c | |||
| 2ca675a90e | |||
| d9647b0086 | |||
| 4e56b4400d | |||
| a34fd72449 | |||
| b22c4d315c | |||
| 192fa8bf05 | |||
| fd12904965 | |||
| f0b71a50f3 | |||
| 57e63251b3 | |||
| 2fafa72157 | |||
| 16b4cc6741 | |||
| c04aeca1d7 | |||
| 03e8d3ce7b | |||
| ea66e5b89f | |||
| fb71ff7ba9 | |||
| aa3435c62e | |||
| e67ffb6b7d | |||
| b3c7358f6f | |||
| 4d9fa16b1e | |||
| 74a9d3b31a | |||
| 4dc7741351 | |||
| f1b3e3b241 | |||
| e72c90a69d | |||
| 1f9630b394 | |||
| 0407a731de | |||
| 3a3702f7a4 | |||
| 6899fa3026 | |||
| f12f53aaab | |||
| 937454899c | |||
| 286a24b8cc | |||
| 14885379da | |||
| 20d50eb2b7 | |||
| e6efd5eaf3 | |||
| 56a96ecf6c | |||
| c49f1c6597 | |||
| 58e2cd8c37 | |||
| d7ef7a7a04 | |||
| dbc992f07e | |||
| 508caabbc5 | |||
| d2e7153fdc | |||
| f6ad1903b7 | |||
| 4ed69a6187 | |||
| 65fae5d1b6 | |||
| 612a7260fc | |||
| 708f4d6073 | |||
| 7294e9679c | |||
| 7a51ea663e | |||
| 3ec4c55ec0 | |||
| ba2214598c | |||
| 5f9d9d7690 | |||
| c48e8d3860 | |||
| 14dfcca0ba | |||
| d47e948acf | |||
| 4a4d6a4279 | |||
| 1ebbeeef36 | |||
| a0269794c5 | |||
| e0f5068190 | |||
| a1d77c4916 | |||
| cccd3aca57 | |||
| 4bc7f98285 | |||
| 85690d6411 | |||
| c45fc7181b | |||
| 064506d6f9 | |||
| d3e3ef3516 | |||
| d2d2470716 | |||
| be75b1fd9b | |||
| 874014747a | |||
| a956471a44 | |||
| 302bb8ee08 | |||
| 948d2f43c8 | |||
| 326957d732 | |||
| b0271a56d9 | |||
| ba4b629816 | |||
| f6ee851773 | |||
| a811c8a5c3 | |||
| a3f03a40af | |||
| 7b585bfe64 | |||
| be0b6797ad | |||
| a368694f24 | |||
| bbfd3b1cee | |||
| c571618689 | |||
| a0689ae1ac | |||
| 52bdecf89d | |||
| d3b6906ffc | |||
| 6f4658db9c | |||
| 09e9322666 | |||
| 7b552d2df9 | |||
| d6c527e422 | |||
| 082c5c8c55 | |||
| 9832c2a95b | |||
| 513f61399d | |||
| bc5c862ec5 | |||
| 863b31d423 | |||
| 289d0a0965 | |||
| 613355f481 | |||
| 59a6da24d2 | |||
| 55d45031a9 | |||
| e6596b3c5d | |||
| 6b8062d1ed | |||
| 8522cc99a8 | |||
| a5e04542cb | |||
| 622d6fa9d1 | |||
| da886799aa | |||
| 17ace68152 | |||
| d8243ece6e | |||
| 0652e01780 | |||
| 25312f6fdf | |||
| 0b7c7983f7 | |||
| 04218b42ad | |||
| c667c62c11 | |||
| 3dc450f624 | |||
| dc36965bb7 | |||
| cdcd77e39c | |||
| 54e310b1e4 | |||
| 6096a4a1ed | |||
| 66e86ba1cf | |||
| 04792e998a | |||
| 13287acd12 | |||
| d8bcff11a7 | |||
| 3c7dfd935e | |||
| e989cafe12 | |||
| b62c6072ed | |||
| 92a19a968d | |||
| e32a5e7e46 | |||
| c961f6b2cf | |||
| 1cf5309deb | |||
| 278546d1c6 | |||
| bc8bab6100 | |||
| a2c1b1fe1f | |||
| d3a6d2a50f | |||
| 8eb13121a4 | |||
| 6bf43fa920 | |||
| a8c5418b2f | |||
| f9d2eaade9 | |||
| 9065abdb98 | |||
| 545b237894 | |||
| 92638f3426 | |||
| b718e9714e | |||
| 73e8a9f928 | |||
| 8f7cfeebe0 | |||
| 1fb5839047 | |||
| e04d5cba8d | |||
| 1a007506d6 | |||
| 50cec28c33 | |||
| cf3e9ee99e | |||
| 7707c7762c | |||
| e7dbdc28a7 | |||
| b1ac65eaa4 | |||
| f2a4a79663 | |||
| 5e84e6a4d5 | |||
| 8b1f3db442 | |||
| c37f5bc357 | |||
| 574a053e93 | |||
| a666e0d381 | |||
| 52d954ca6d | |||
| 8fe4e41b5b | |||
| eb578a304f | |||
| e79176a622 | |||
| 5f6b48a9b5 | |||
| 4ec6623ed2 | |||
| df7366a453 | |||
| 8bf8b28885 | |||
| 642e25aaed | |||
| 20d57a7f7d | |||
| 38104f37e2 | |||
| 6bbcb9d964 | |||
| 35ce0408d9 | |||
| 7689d4129f | |||
| 8d828e1fc3 | |||
| 06f4ab7c3f | |||
| 12aad7b9d1 | |||
| 5986c9ce7e | |||
| 19fa553138 | |||
| ea68e19044 | |||
| 40a3166472 | |||
| 3e192b0edd | |||
| 60f2535597 | |||
| 1e648e2bac | |||
| 4fb37b742d | |||
| 58607e1958 | |||
| 785d2c2712 | |||
| 15368ef3b2 | |||
| 6d6b286420 | |||
| 83ccfc55db | |||
| 7e41ce666e | |||
| 9163510905 | |||
| 4631e1728a | |||
| 551863b640 | |||
| 9293e0b333 | |||
| 9a8a8f964b | |||
| dd17a759c1 | |||
| 1fc36abe56 | |||
| eb55f1c04d | |||
| ba518b7864 | |||
| 506652293e | |||
| ff667b6617 | |||
| e795e4b2ea | |||
| 55edda14bf | |||
| 770f786720 | |||
| 6d4bd49ac7 | |||
| bf3b1a05e8 | |||
| 763d121b85 | |||
| 64d59d9b4c | |||
| 356978af9a | |||
| f16854859a | |||
| a490e1e7a5 | |||
| 7db3f9ad19 | |||
| 9c7f73a857 | |||
| 9e4aba597b | |||
| c9b1bfd5dd | |||
| 162acc15ad | |||
| e2c95b3904 | |||
| 503c170ede | |||
| 40032c15e2 | |||
| 5548e6531a | |||
| 92c4b0b4f6 | |||
| a2404fb1b9 | |||
| 695c1e7715 | |||
| f2c6b669ad | |||
| 4822b3e7b8 | |||
| 068837dce4 | |||
| 54b5661f35 | |||
| 7fc4979ff4 | |||
| ce92a306a2 | |||
| 38b3bb9c08 | |||
| d3893904ed | |||
| b14a75b28b | |||
| 82481fc1cf | |||
| 2ca2410843 | |||
| 7641203b2e | |||
| de6f589f96 | |||
| 5c062c4f0b | |||
| 0fd5541e51 | |||
| b547d8d27e | |||
| 09aace0ffe | |||
| 4db3a08f19 | |||
| 933c63c904 | |||
| 2f8601ee06 | |||
| 59211ce36e | |||
| bfea178fc4 | |||
| d0889cbd3d | |||
| 7e0d7a61d9 | |||
| e25a70302d | |||
| 5366865002 | |||
| df7d1fcb73 | |||
| 1bce14a668 | |||
| b52af01444 | |||
| 09370c78d0 | |||
| 6ad3797896 | |||
| ee116ee460 | |||
| e2f60038bb | |||
| c2afd4efc0 | |||
| 637af26463 | |||
| 75fafb6bd7 | |||
| b56e45262a | |||
| 7d9bf2e6c2 | |||
| 214018109d | |||
| b5cefbedda | |||
| 4138bab0e8 | |||
| fd0f634621 | |||
| 0682560ad8 | |||
| 747f9b207a | |||
| b0377ef865 | |||
| f890b4139a | |||
| 7e0cdf30af | |||
| 2cc2b70f40 | |||
| b84a8ccb53 | |||
| 1743a7a18f | |||
| 4cb2714995 | |||
| dea13b461e | |||
| b2affab6b8 | |||
| ebb8777932 | |||
| 7fce1e47d8 | |||
| ce68df713b | |||
| 4bf5327c64 | |||
| 67af4b1f2b | |||
| 465ff72ff2 | |||
| 3ea71da4ba | |||
| 436cc20a0b | |||
| b7c43e5919 | |||
| 83185e6f28 | |||
| f57a5e5975 | |||
| 0f11ccc288 | |||
| 85610d925c | |||
| 000f77224c | |||
| 2749dc54ad | |||
| 23e5de77b7 | |||
| ebe6d10848 | |||
| 3d4e3e92c0 | |||
| e8cacdcfdd | |||
| abed371df2 | |||
| f0b07cbf58 | |||
| 34f2b917e5 | |||
| d8a1c47dd4 | |||
| 5eac2c50fa | |||
| db590df608 |
+18
@@ -0,0 +1,18 @@
|
||||
uploads/*
|
||||
templates_c/*
|
||||
serendipity_config_local.inc.php
|
||||
.cvsignore
|
||||
.htaccess*
|
||||
*.db
|
||||
private/*
|
||||
archives/*
|
||||
*~
|
||||
DEADJOE
|
||||
plugins/additional_plugins*
|
||||
/.settings
|
||||
/.buildpath
|
||||
/.project
|
||||
.DS_Store
|
||||
.editorconfig
|
||||
*.git
|
||||
tests/phpunit.xml
|
||||
@@ -1,3 +1,4 @@
|
||||
# Serendipity - a PHP Weblog/Blog software
|
||||
|
||||
[Serendipity](http://s9y.org) is a PHP-powered weblog application which gives the user an easy way to maintain an online diary, weblog or even a complete homepage. While the default package is designed for the casual blogger, Serendipity offers a flexible, expandable and easy-to-use framework with the power for professional applications.
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
Cache_Lite 1.5.1
|
||||
HTTP_Request 1.2.4
|
||||
Net_CheckIP 1.1
|
||||
Net_Socket 1.0.6
|
||||
Net_URL 1.0.14
|
||||
PEAR 1.3.5
|
||||
Text_Wiki 0.25.0
|
||||
XML_RPC 1.4.0
|
||||
Onyx 1.0 (customized)
|
||||
Smarty 2.6.9
|
||||
Net_DNSBL 1.0.0
|
||||
Cache_Lite 1.5.1 (CVS 1.54)
|
||||
HTTP_Request 1.2.4 (CVS 1.43)
|
||||
HTTP_Request2 2.2.1 (CVS 2.2.1)
|
||||
Net_CheckIP 1.1 (CVS 1.5)
|
||||
Net_DNSBL 1.0.0 (CVS 1.4)
|
||||
Net_Socket 1.0.6 (CVS 1.24)
|
||||
Net_URL 1.0.4 (CVS 1.36)
|
||||
Net_SURBL 1.4
|
||||
Onyx (customized) 1.0
|
||||
PEAR 1.9.5 (CVS 1.83)
|
||||
SimplePie 1.2.1
|
||||
Smarty 3.1.18
|
||||
Text_Wiki 0.25.0 (CVS 1.27)
|
||||
XML_RPC 1.4.0 (1.5.5)
|
||||
|
||||
|
||||
+63
-12
@@ -19,8 +19,8 @@
|
||||
*
|
||||
* @package Cache_Lite
|
||||
* @category Caching
|
||||
* @version $Id: Lite.php,v 1.54 2009/07/07 05:34:37 tacker Exp $
|
||||
* @author Fabien MARTY <fab@php.net>
|
||||
* @author Markus Tacker <tacker@php.net>
|
||||
*/
|
||||
|
||||
define('CACHE_LITE_ERROR_RETURN', 1);
|
||||
@@ -247,6 +247,12 @@ class Cache_Lite
|
||||
* @var boolean
|
||||
*/
|
||||
var $_errorHandlingAPIBreak = false;
|
||||
|
||||
var $_hashedDirectoryGroup = NULL;
|
||||
|
||||
var $_cacheFileMode = NULL;
|
||||
|
||||
var $_cacheFileGroup = NULL;
|
||||
|
||||
// --- Public methods ---
|
||||
|
||||
@@ -272,16 +278,30 @@ class Cache_Lite
|
||||
* 'hashedDirectoryLevel' => level of the hashed directory system (int),
|
||||
* 'hashedDirectoryUmask' => umask for hashed directory structure (int),
|
||||
* 'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
|
||||
* 'hashedDirectoryGroup' => group of hashed directory structure (int | string) (see function chgrp)
|
||||
* 'cacheFileMode' => filesystem mode of newly created cache files (int)
|
||||
* 'cacheFileGroup' => group of newly created cache files (int | string) (see function chgrp)
|
||||
* );
|
||||
*
|
||||
* If sys_get_temp_dir() is available and the
|
||||
* 'cacheDir' option is not provided in the
|
||||
* constructor options array its output is used
|
||||
* to determine the suitable temporary directory.
|
||||
*
|
||||
* @see http://de.php.net/sys_get_temp_dir
|
||||
* @see http://pear.php.net/bugs/bug.php?id=18328
|
||||
*
|
||||
* @param array $options options
|
||||
* @access public
|
||||
*/
|
||||
function Cache_Lite($options = array(NULL))
|
||||
function __construct($options = array(NULL))
|
||||
{
|
||||
foreach($options as $key => $value) {
|
||||
$this->setOption($key, $value);
|
||||
}
|
||||
if (!isset($options['cacheDir']) && function_exists('sys_get_temp_dir')) {
|
||||
$this->setOption('cacheDir', sys_get_temp_dir() . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +315,7 @@ class Cache_Lite
|
||||
*/
|
||||
function setOption($name, $value)
|
||||
{
|
||||
$availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
|
||||
$availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode', 'hashedDirectoryGroup', 'cacheFileMode', 'cacheFileGroup');
|
||||
if (in_array($name, $availableOptions)) {
|
||||
$property = '_'.$name;
|
||||
$this->$property = $value;
|
||||
@@ -534,7 +554,7 @@ class Cache_Lite
|
||||
*/
|
||||
function raiseError($msg, $code)
|
||||
{
|
||||
include_once dirname(__FILE__) . '/../PEAR.php';
|
||||
include_once('PEAR.php');
|
||||
return PEAR::raiseError($msg, $code, $this->_pearErrorMode);
|
||||
}
|
||||
|
||||
@@ -613,7 +633,7 @@ class Cache_Lite
|
||||
return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
|
||||
}
|
||||
$result = true;
|
||||
while ($file = readdir($dh)) {
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
if (($file != '.') && ($file != '..')) {
|
||||
if (substr($file, 0, 6)=='cache_') {
|
||||
$file2 = $dir . $file;
|
||||
@@ -654,7 +674,19 @@ class Cache_Lite
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Touch the cache file while are recreating it to avoid
|
||||
* launch this task more then once when necessary
|
||||
* When the cache recreated and Added in Cache Memory
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
function _touchCacheFile(){
|
||||
if (file_exists($this->_file)) {
|
||||
@touch($this->_file);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add some date in the memory caching array
|
||||
*
|
||||
@@ -663,6 +695,7 @@ class Cache_Lite
|
||||
*/
|
||||
function _memoryCacheAdd($data)
|
||||
{
|
||||
$this->_touchCacheFile();
|
||||
$this->_memoryCachingArray[$this->_file] = $data;
|
||||
if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
|
||||
list($key, ) = each($this->_memoryCachingArray);
|
||||
@@ -707,8 +740,8 @@ class Cache_Lite
|
||||
function _read()
|
||||
{
|
||||
$fp = @fopen($this->_file, "rb");
|
||||
if ($this->_fileLocking) @flock($fp, LOCK_SH);
|
||||
if ($fp) {
|
||||
if ($this->_fileLocking) @flock($fp, LOCK_SH);
|
||||
clearstatcache();
|
||||
$length = @filesize($this->_file);
|
||||
$mqr = get_magic_quotes_runtime();
|
||||
@@ -718,9 +751,13 @@ class Cache_Lite
|
||||
if ($this->_readControl) {
|
||||
$hashControl = @fread($fp, 32);
|
||||
$length = $length - 32;
|
||||
}
|
||||
}
|
||||
|
||||
if ($length) {
|
||||
$data = @fread($fp, $length);
|
||||
$data = '';
|
||||
// See https://bugs.php.net/bug.php?id=30936
|
||||
// The 8192 magic number is the chunk size used internally by PHP.
|
||||
while(!feof($fp)) $data .= fread($fp, 8192);
|
||||
} else {
|
||||
$data = '';
|
||||
}
|
||||
@@ -760,13 +797,29 @@ class Cache_Lite
|
||||
for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
|
||||
$root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
|
||||
if (!(@is_dir($root))) {
|
||||
@mkdir($root, $this->_hashedDirectoryUmask);
|
||||
if (@mkdir($root))
|
||||
{
|
||||
@chmod($root, $this->_hashedDirectoryUmask);
|
||||
if (! is_null($this->_hashedDirectoryGroup))
|
||||
@chgrp($root, $this->_hashedDirectoryGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if both _cacheFileMode and _cacheFileGroup is null, then we don't need to call
|
||||
// file_exists (see below: if ($is_newfile) ...)
|
||||
$is_newfile = (! is_null($this->_cacheFileMode) || !is_null($this->_cacheFileGroup))
|
||||
&& ! @file_exists($this->_file);
|
||||
$fp = @fopen($this->_file, "wb");
|
||||
if ($fp) {
|
||||
if ($this->_fileLocking) @flock($fp, LOCK_EX);
|
||||
if ($is_newfile)
|
||||
{
|
||||
if (! is_null($this->_cacheFileMode))
|
||||
@chmod($this->_file, $this->_cacheFileMode);
|
||||
if (! is_null($this->_cacheFileGroup))
|
||||
@chgrp($this->_file, $this->_cacheFileGroup);
|
||||
}
|
||||
if ($this->_readControl) {
|
||||
@fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
|
||||
}
|
||||
@@ -831,5 +884,3 @@ class Cache_Lite
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class extends Cache_Lite and offers a cache system driven by a master file
|
||||
*
|
||||
* With this class, cache validity is only dependent of a given file. Cache files
|
||||
* are valid only if they are older than the master file. It's a perfect way for
|
||||
* caching templates results (if the template file is newer than the cache, cache
|
||||
* must be rebuild...) or for config classes...
|
||||
* There are some examples in the 'docs/examples' file
|
||||
* Technical choices are described in the 'docs/technical' file
|
||||
*
|
||||
* @package Cache_Lite
|
||||
* @author Fabien MARTY <fab@php.net>
|
||||
*/
|
||||
|
||||
require_once('Cache/Lite.php');
|
||||
|
||||
class Cache_Lite_File extends Cache_Lite
|
||||
{
|
||||
|
||||
// --- Private properties ---
|
||||
|
||||
/**
|
||||
* Complete path of the file used for controlling the cache lifetime
|
||||
*
|
||||
* @var string $_masterFile
|
||||
*/
|
||||
var $_masterFile = '';
|
||||
|
||||
/**
|
||||
* Masterfile mtime
|
||||
*
|
||||
* @var int $_masterFile_mtime
|
||||
*/
|
||||
var $_masterFile_mtime = 0;
|
||||
|
||||
// --- Public methods ----
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* $options is an assoc. To have a look at availables options,
|
||||
* see the constructor of the Cache_Lite class in 'Cache_Lite.php'
|
||||
*
|
||||
* Comparing to Cache_Lite constructor, there is another option :
|
||||
* $options = array(
|
||||
* (...) see Cache_Lite constructor
|
||||
* 'masterFile' => complete path of the file used for controlling the cache lifetime(string)
|
||||
* );
|
||||
*
|
||||
* @param array $options options
|
||||
* @access public
|
||||
*/
|
||||
function __construct($options = array(NULL))
|
||||
{
|
||||
$options['lifetime'] = 0;
|
||||
parent::__construct($options);
|
||||
if (isset($options['masterFile'])) {
|
||||
$this->_masterFile = $options['masterFile'];
|
||||
} else {
|
||||
return $this->raiseError('Cache_Lite_File : masterFile option must be set !');
|
||||
}
|
||||
if (!($this->_masterFile_mtime = @filemtime($this->_masterFile))) {
|
||||
return $this->raiseError('Cache_Lite_File : Unable to read masterFile : '.$this->_masterFile, -3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a cache is available and (if yes) return it
|
||||
*
|
||||
* @param string $id cache id
|
||||
* @param string $group name of the cache group
|
||||
* @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
|
||||
* @return string data of the cache (else : false)
|
||||
* @access public
|
||||
*/
|
||||
function get($id, $group = 'default', $doNotTestCacheValidity = false)
|
||||
{
|
||||
if ($data = parent::get($id, $group, true)) {
|
||||
if ($filemtime = $this->lastModified()) {
|
||||
if ($filemtime > $this->_masterFile_mtime) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,12 +11,11 @@
|
||||
* Technical choices are described in the 'docs/technical' file
|
||||
*
|
||||
* @package Cache_Lite
|
||||
* @version $Id: Function.php,v 1.11 2006/12/14 12:59:43 cweiske Exp $
|
||||
* @author Sebastian BERGMANN <sb@sebastian-bergmann.de>
|
||||
* @author Fabien MARTY <fab@php.net>
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../Lite.php';
|
||||
require_once('Cache/Lite.php');
|
||||
|
||||
class Cache_Lite_Function extends Cache_Lite
|
||||
{
|
||||
@@ -82,7 +81,7 @@ class Cache_Lite_Function extends Cache_Lite
|
||||
* @param array $options options
|
||||
* @access public
|
||||
*/
|
||||
function Cache_Lite_Function($options = array(NULL))
|
||||
function __construct($options = array(NULL))
|
||||
{
|
||||
$availableOptions = array('debugCacheLiteFunction', 'defaultGroup', 'dontCacheWhenTheOutputContainsNOCACHE', 'dontCacheWhenTheResultIsFalse', 'dontCacheWhenTheResultIsNull');
|
||||
while (list($name, $value) = each($options)) {
|
||||
@@ -92,7 +91,7 @@ class Cache_Lite_Function extends Cache_Lite
|
||||
}
|
||||
}
|
||||
reset($options);
|
||||
$this->Cache_Lite($options);
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,5 +206,3 @@ class Cache_Lite_Function extends Cache_Lite
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class extends Cache_Lite and uses output buffering to get the data to cache.
|
||||
* It supports nesting of caches
|
||||
*
|
||||
* @package Cache_Lite
|
||||
* @author Markus Tacker <tacker@php.net>
|
||||
*/
|
||||
|
||||
require_once('Cache/Lite/Output.php');
|
||||
|
||||
class Cache_Lite_NestedOutput extends Cache_Lite_Output
|
||||
{
|
||||
private $nestedIds = array();
|
||||
private $nestedGroups = array();
|
||||
|
||||
/**
|
||||
* Start the cache
|
||||
*
|
||||
* @param string $id cache id
|
||||
* @param string $group name of the cache group
|
||||
* @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
|
||||
* @return boolean|string false if the cache is not hit else the data
|
||||
* @access public
|
||||
*/
|
||||
function start($id, $group = 'default', $doNotTestCacheValidity = false)
|
||||
{
|
||||
$this->nestedIds[] = $id;
|
||||
$this->nestedGroups[] = $group;
|
||||
$data = $this->get($id, $group, $doNotTestCacheValidity);
|
||||
if ($data !== false) {
|
||||
return $data;
|
||||
}
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the cache
|
||||
*
|
||||
* @param boolen
|
||||
* @return string return contents of cache
|
||||
*/
|
||||
function end()
|
||||
{
|
||||
$data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$id = array_pop($this->nestedIds);
|
||||
$group = array_pop($this->nestedGroups);
|
||||
$this->save($data, $id, $group);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,11 +7,10 @@
|
||||
* Technical choices are described in the 'docs/technical' file
|
||||
*
|
||||
* @package Cache_Lite
|
||||
* @version $Id: Output.php,v 1.4 2006/01/29 00:22:07 fab Exp $
|
||||
* @author Fabien MARTY <fab@php.net>
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../Lite.php';
|
||||
require_once('Cache/Lite.php');
|
||||
|
||||
class Cache_Lite_Output extends Cache_Lite
|
||||
{
|
||||
@@ -27,9 +26,9 @@ class Cache_Lite_Output extends Cache_Lite
|
||||
* @param array $options options
|
||||
* @access public
|
||||
*/
|
||||
function Cache_Lite_Output($options)
|
||||
function __construct($options)
|
||||
{
|
||||
$this->Cache_Lite($options);
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +66,3 @@ class Cache_Lite_Output extends Cache_Lite
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -89,7 +89,7 @@ class HTTP_Request {
|
||||
* @var string
|
||||
*/
|
||||
var $_user;
|
||||
|
||||
|
||||
/**
|
||||
* Basic Auth Password
|
||||
* @var string
|
||||
@@ -101,25 +101,25 @@ class HTTP_Request {
|
||||
* @var object Net_Socket
|
||||
*/
|
||||
var $_sock;
|
||||
|
||||
|
||||
/**
|
||||
* Proxy server
|
||||
* @var string
|
||||
*/
|
||||
var $_proxy_host;
|
||||
|
||||
|
||||
/**
|
||||
* Proxy port
|
||||
* @var integer
|
||||
*/
|
||||
var $_proxy_port;
|
||||
|
||||
|
||||
/**
|
||||
* Proxy username
|
||||
* @var string
|
||||
*/
|
||||
var $_proxy_user;
|
||||
|
||||
|
||||
/**
|
||||
* Proxy password
|
||||
* @var string
|
||||
@@ -133,7 +133,7 @@ class HTTP_Request {
|
||||
var $_postData;
|
||||
|
||||
/**
|
||||
* Request body
|
||||
* Request body
|
||||
* @var string
|
||||
*/
|
||||
var $_body;
|
||||
@@ -145,7 +145,7 @@ class HTTP_Request {
|
||||
var $_bodyDisallowed = array('TRACE');
|
||||
|
||||
/**
|
||||
* Files to post
|
||||
* Files to post
|
||||
* @var array
|
||||
*/
|
||||
var $_postFiles = array();
|
||||
@@ -155,25 +155,25 @@ class HTTP_Request {
|
||||
* @var float
|
||||
*/
|
||||
var $_timeout;
|
||||
|
||||
|
||||
/**
|
||||
* HTTP_Response object
|
||||
* @var object HTTP_Response
|
||||
*/
|
||||
var $_response;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to allow redirects
|
||||
* @var boolean
|
||||
*/
|
||||
var $_allowRedirects;
|
||||
|
||||
|
||||
/**
|
||||
* Maximum redirects allowed
|
||||
* @var integer
|
||||
*/
|
||||
var $_maxRedirects;
|
||||
|
||||
|
||||
/**
|
||||
* Current number of redirects
|
||||
* @var integer
|
||||
@@ -193,7 +193,7 @@ class HTTP_Request {
|
||||
var $_listeners = array();
|
||||
|
||||
/**
|
||||
* Whether to save response body in response object property
|
||||
* Whether to save response body in response object property
|
||||
* @var bool
|
||||
*/
|
||||
var $_saveBody = true;
|
||||
@@ -286,7 +286,7 @@ class HTTP_Request {
|
||||
$this->addHeader('Accept-Encoding', 'gzip');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a Host header for HTTP/1.1 requests
|
||||
*
|
||||
@@ -303,14 +303,14 @@ class HTTP_Request {
|
||||
|
||||
} elseif ($this->_url->port == 443 AND strcasecmp($this->_url->protocol, 'https') == 0 AND strpos($this->_url->url, ':443') !== false) {
|
||||
$host = $this->_url->host . ':' . $this->_url->port;
|
||||
|
||||
|
||||
} else {
|
||||
$host = $this->_url->host;
|
||||
}
|
||||
|
||||
return $host;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resets the object to its initial state (DEPRECATED).
|
||||
* Takes the same parameters as the constructor.
|
||||
@@ -344,7 +344,7 @@ class HTTP_Request {
|
||||
$this->addHeader('Host', $this->_generateHostHeader());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a proxy to be used
|
||||
*
|
||||
@@ -438,8 +438,8 @@ class HTTP_Request {
|
||||
function addQueryString($name, $value, $preencoded = false)
|
||||
{
|
||||
$this->_url->addQueryString($name, $value, $preencoded);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the querystring to literally what you supply
|
||||
*
|
||||
@@ -546,7 +546,7 @@ class HTTP_Request {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any postdata that has been added (DEPRECATED).
|
||||
* Clears any postdata that has been added (DEPRECATED).
|
||||
*
|
||||
* Useful for multiple request scenarios.
|
||||
*
|
||||
@@ -570,9 +570,9 @@ class HTTP_Request {
|
||||
$cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : '';
|
||||
$this->addHeader('Cookie', $cookies . $name . '=' . $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears any cookies that have been added (DEPRECATED).
|
||||
* Clears any cookies that have been added (DEPRECATED).
|
||||
*
|
||||
* Useful for multiple request scenarios
|
||||
*
|
||||
@@ -594,7 +594,7 @@ class HTTP_Request {
|
||||
*/
|
||||
function sendRequest($saveBody = true)
|
||||
{
|
||||
if (!is_a($this->_url, 'Net_URL')) {
|
||||
if (!($this->_url instanceof Net_URL)) {
|
||||
return PEAR::raiseError('No URL given.');
|
||||
}
|
||||
|
||||
@@ -645,7 +645,7 @@ class HTTP_Request {
|
||||
AND $this->getResponseCode() < 399
|
||||
AND !empty($this->_response->_headers['location'])) {
|
||||
|
||||
|
||||
|
||||
$redirect = $this->_response->_headers['location'];
|
||||
|
||||
// Absolute URL
|
||||
@@ -655,7 +655,7 @@ class HTTP_Request {
|
||||
// Absolute path
|
||||
} elseif ($redirect[0] == '/') {
|
||||
$this->_url->path = $redirect;
|
||||
|
||||
|
||||
// Relative path
|
||||
} elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') {
|
||||
if (substr($this->_url->path, -1) == '/') {
|
||||
@@ -665,7 +665,7 @@ class HTTP_Request {
|
||||
}
|
||||
$redirect = Net_URL::resolvePath($redirect);
|
||||
$this->_url->path = $redirect;
|
||||
|
||||
|
||||
// Filename, no path
|
||||
} else {
|
||||
if (substr($this->_url->path, -1) == '/') {
|
||||
@@ -842,7 +842,7 @@ class HTTP_Request {
|
||||
$request .= 'Content-Length: ' . strlen($this->_body) . "\r\n\r\n";
|
||||
$request .= $this->_body;
|
||||
}
|
||||
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
@@ -885,7 +885,7 @@ class HTTP_Request {
|
||||
*/
|
||||
function attach(&$listener)
|
||||
{
|
||||
if (!is_a($listener, 'HTTP_Request_Listener')) {
|
||||
if (!($listener instanceof HTTP_Request_Listener)) {
|
||||
return false;
|
||||
}
|
||||
$this->_listeners[$listener->getId()] =& $listener;
|
||||
@@ -894,7 +894,7 @@ class HTTP_Request {
|
||||
|
||||
|
||||
/**
|
||||
* Removes a Listener from the list of listeners
|
||||
* Removes a Listener from the list of listeners
|
||||
*
|
||||
* @param object HTTP_Request_Listener instance to detach
|
||||
* @return boolean whether the listener was successfully detached
|
||||
@@ -902,7 +902,7 @@ class HTTP_Request {
|
||||
*/
|
||||
function detach(&$listener)
|
||||
{
|
||||
if (!is_a($listener, 'HTTP_Request_Listener') ||
|
||||
if (!($listener instanceof HTTP_Request_Listener) ||
|
||||
!isset($this->_listeners[$listener->getId()])) {
|
||||
return false;
|
||||
}
|
||||
@@ -951,13 +951,13 @@ class HTTP_Response
|
||||
* @var string
|
||||
*/
|
||||
var $_protocol;
|
||||
|
||||
|
||||
/**
|
||||
* Return code
|
||||
* @var string
|
||||
*/
|
||||
var $_code;
|
||||
|
||||
|
||||
/**
|
||||
* Response headers
|
||||
* @var array
|
||||
@@ -965,7 +965,7 @@ class HTTP_Response
|
||||
var $_headers;
|
||||
|
||||
/**
|
||||
* Cookies set in response
|
||||
* Cookies set in response
|
||||
* @var array
|
||||
*/
|
||||
var $_cookies;
|
||||
@@ -1078,7 +1078,7 @@ class HTTP_Response
|
||||
list($headername, $headervalue) = explode(':', $header, 2);
|
||||
$headername = strtolower($headername);
|
||||
$headervalue = ltrim($headervalue);
|
||||
|
||||
|
||||
if ('set-cookie' != $headername) {
|
||||
if (isset($this->_headers[$headername])) {
|
||||
$this->_headers[$headername] .= ',' . $headervalue;
|
||||
@@ -1154,7 +1154,7 @@ class HTTP_Response
|
||||
if (0 == $this->_chunkLength) {
|
||||
$line = $this->_sock->readLine();
|
||||
if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) {
|
||||
$this->_chunkLength = hexdec($matches[1]);
|
||||
$this->_chunkLength = hexdec($matches[1]);
|
||||
// Chunk with zero length indicates the end
|
||||
if (0 == $this->_chunkLength) {
|
||||
$this->_sock->readLine(); // make this an eof()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*/
|
||||
require_once 'HTTP/Request2/Response.php';
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*
|
||||
* HTTP_Request2 class itself only defines methods for aggregating the request
|
||||
* data, all actual work of sending the request to the remote server and
|
||||
* receiving its response is performed by adapters.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
abstract class HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A list of methods that MUST NOT have a request body, per RFC 2616
|
||||
* @var array
|
||||
*/
|
||||
protected static $bodyDisallowed = array('TRACE');
|
||||
|
||||
/**
|
||||
* Methods having defined semantics for request body
|
||||
*
|
||||
* Content-Length header (indicating that the body follows, section 4.3 of
|
||||
* RFC 2616) will be sent for these methods even if no body was added
|
||||
*
|
||||
* @var array
|
||||
* @link http://pear.php.net/bugs/bug.php?id=12900
|
||||
* @link http://pear.php.net/bugs/bug.php?id=14740
|
||||
*/
|
||||
protected static $bodyRequired = array('POST', 'PUT');
|
||||
|
||||
/**
|
||||
* Request being sent
|
||||
* @var HTTP_Request2
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Request body
|
||||
* @var string|resource|HTTP_Request2_MultipartBody
|
||||
* @see HTTP_Request2::getBody()
|
||||
*/
|
||||
protected $requestBody;
|
||||
|
||||
/**
|
||||
* Length of the request body
|
||||
* @var integer
|
||||
*/
|
||||
protected $contentLength;
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
abstract public function sendRequest(HTTP_Request2 $request);
|
||||
|
||||
/**
|
||||
* Calculates length of the request body, adds proper headers
|
||||
*
|
||||
* @param array &$headers associative array of request headers, this method
|
||||
* will add proper 'Content-Length' and 'Content-Type'
|
||||
* headers to this array (or remove them if not needed)
|
||||
*/
|
||||
protected function calculateRequestLength(&$headers)
|
||||
{
|
||||
$this->requestBody = $this->request->getBody();
|
||||
|
||||
if (is_string($this->requestBody)) {
|
||||
$this->contentLength = strlen($this->requestBody);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$stat = fstat($this->requestBody);
|
||||
$this->contentLength = $stat['size'];
|
||||
rewind($this->requestBody);
|
||||
} else {
|
||||
$this->contentLength = $this->requestBody->getLength();
|
||||
$headers['content-type'] = 'multipart/form-data; boundary=' .
|
||||
$this->requestBody->getBoundary();
|
||||
$this->requestBody->rewind();
|
||||
}
|
||||
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed)
|
||||
|| 0 == $this->contentLength
|
||||
) {
|
||||
// No body: send a Content-Length header nonetheless (request #12900),
|
||||
// but do that only for methods that require a body (bug #14740)
|
||||
if (in_array($this->request->getMethod(), self::$bodyRequired)) {
|
||||
$headers['content-length'] = 0;
|
||||
} else {
|
||||
unset($headers['content-length']);
|
||||
// if the method doesn't require a body and doesn't have a
|
||||
// body, don't send a Content-Type header. (request #16799)
|
||||
unset($headers['content-type']);
|
||||
}
|
||||
} else {
|
||||
if (empty($headers['content-type'])) {
|
||||
$headers['content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
// Content-Length should not be sent for chunked Transfer-Encoding (bug #20125)
|
||||
if (!isset($headers['transfer-encoding'])) {
|
||||
$headers['content-length'] = $this->contentLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,577 @@
|
||||
<?php
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Adapter for HTTP_Request2 wrapping around cURL extension
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* Mapping of header names to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $headerMap = array(
|
||||
'accept-encoding' => CURLOPT_ENCODING,
|
||||
'cookie' => CURLOPT_COOKIE,
|
||||
'referer' => CURLOPT_REFERER,
|
||||
'user-agent' => CURLOPT_USERAGENT
|
||||
);
|
||||
|
||||
/**
|
||||
* Mapping of SSL context options to cURL options
|
||||
* @var array
|
||||
*/
|
||||
protected static $sslContextMap = array(
|
||||
'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
|
||||
'ssl_cafile' => CURLOPT_CAINFO,
|
||||
'ssl_capath' => CURLOPT_CAPATH,
|
||||
'ssl_local_cert' => CURLOPT_SSLCERT,
|
||||
'ssl_passphrase' => CURLOPT_SSLCERTPASSWD
|
||||
);
|
||||
|
||||
/**
|
||||
* Mapping of CURLE_* constants to Exception subclasses and error codes
|
||||
* @var array
|
||||
*/
|
||||
protected static $errorMap = array(
|
||||
CURLE_UNSUPPORTED_PROTOCOL => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_COULDNT_RESOLVE_PROXY => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_COULDNT_RESOLVE_HOST => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_COULDNT_CONNECT => array('HTTP_Request2_ConnectionException'),
|
||||
// error returned from write callback
|
||||
CURLE_WRITE_ERROR => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_OPERATION_TIMEOUTED => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::TIMEOUT),
|
||||
CURLE_HTTP_RANGE_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_CONNECT_ERROR => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_LIBRARY_NOT_FOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_FUNCTION_NOT_FOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_ABORTED_BY_CALLBACK => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::NON_HTTP_REDIRECT),
|
||||
CURLE_TOO_MANY_REDIRECTS => array('HTTP_Request2_MessageException',
|
||||
HTTP_Request2_Exception::TOO_MANY_REDIRECTS),
|
||||
CURLE_SSL_PEER_CERTIFICATE => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_GOT_NOTHING => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_ENGINE_NOTFOUND => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_SSL_ENGINE_SETFAILED => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION),
|
||||
CURLE_SEND_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_RECV_ERROR => array('HTTP_Request2_MessageException'),
|
||||
CURLE_SSL_CERTPROBLEM => array('HTTP_Request2_LogicException',
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT),
|
||||
CURLE_SSL_CIPHER => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_SSL_CACERT => array('HTTP_Request2_ConnectionException'),
|
||||
CURLE_BAD_CONTENT_ENCODING => array('HTTP_Request2_MessageException'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Response being received
|
||||
* @var HTTP_Request2_Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* Whether 'sentHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventSentHeaders = false;
|
||||
|
||||
/**
|
||||
* Whether 'receivedHeaders' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventReceivedHeaders = false;
|
||||
|
||||
/**
|
||||
* Whether 'sentBoody' event was sent to observers
|
||||
* @var boolean
|
||||
*/
|
||||
protected $eventSentBody = false;
|
||||
|
||||
/**
|
||||
* Position within request body
|
||||
* @var integer
|
||||
* @see callbackReadBody()
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Information about last transfer, as returned by curl_getinfo()
|
||||
* @var array
|
||||
*/
|
||||
protected $lastInfo;
|
||||
|
||||
/**
|
||||
* Creates a subclass of HTTP_Request2_Exception from curl error data
|
||||
*
|
||||
* @param resource $ch curl handle
|
||||
*
|
||||
* @return HTTP_Request2_Exception
|
||||
*/
|
||||
protected static function wrapCurlError($ch)
|
||||
{
|
||||
$nativeCode = curl_errno($ch);
|
||||
$message = 'Curl error: ' . curl_error($ch);
|
||||
if (!isset(self::$errorMap[$nativeCode])) {
|
||||
return new HTTP_Request2_Exception($message, 0, $nativeCode);
|
||||
} else {
|
||||
$class = self::$errorMap[$nativeCode][0];
|
||||
$code = empty(self::$errorMap[$nativeCode][1])
|
||||
? 0 : self::$errorMap[$nativeCode][1];
|
||||
return new $class($message, $code, $nativeCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends request to the remote server and returns its response
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'cURL extension not available', HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
$this->response = null;
|
||||
$this->position = 0;
|
||||
$this->eventSentHeaders = false;
|
||||
$this->eventReceivedHeaders = false;
|
||||
$this->eventSentBody = false;
|
||||
|
||||
try {
|
||||
if (false === curl_exec($ch = $this->createCurlHandle())) {
|
||||
$e = self::wrapCurlError($ch);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
if (isset($ch)) {
|
||||
$this->lastInfo = curl_getinfo($ch);
|
||||
if (CURLE_OK !== curl_errno($ch)) {
|
||||
$this->request->setLastEvent('warning', curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
$response = $this->response;
|
||||
unset($this->request, $this->requestBody, $this->response);
|
||||
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($jar = $request->getCookieJar()) {
|
||||
$jar->addCookiesFromResponse($response);
|
||||
}
|
||||
|
||||
if (0 < $this->lastInfo['size_download']) {
|
||||
$request->setLastEvent('receivedBody', $response);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about last transfer
|
||||
*
|
||||
* @return array associative array as returned by curl_getinfo()
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->lastInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new cURL handle and populates it with data from the request
|
||||
*
|
||||
* @return resource a cURL handle, as created by curl_init()
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_NotImplementedException
|
||||
*/
|
||||
protected function createCurlHandle()
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
// setup write callbacks
|
||||
CURLOPT_HEADERFUNCTION => array($this, 'callbackWriteHeader'),
|
||||
CURLOPT_WRITEFUNCTION => array($this, 'callbackWriteBody'),
|
||||
// buffer size
|
||||
CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'),
|
||||
// connection timeout
|
||||
CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'),
|
||||
// save full outgoing headers, in case someone is interested
|
||||
CURLINFO_HEADER_OUT => true,
|
||||
// request url
|
||||
CURLOPT_URL => $this->request->getUrl()->getUrl()
|
||||
));
|
||||
|
||||
// set up redirects
|
||||
if (!$this->request->getConfig('follow_redirects')) {
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
||||
} else {
|
||||
if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Redirect support in curl is unavailable due to open_basedir or safe_mode setting',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects'));
|
||||
// limit redirects to http(s), works in 5.2.10+
|
||||
if (defined('CURLOPT_REDIR_PROTOCOLS')) {
|
||||
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
}
|
||||
// works in 5.3.2+, http://bugs.php.net/bug.php?id=49571
|
||||
if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR')) {
|
||||
curl_setopt($ch, CURLOPT_POSTREDIR, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// set local IP via CURLOPT_INTERFACE (request #19515)
|
||||
if ($ip = $this->request->getConfig('local_ip')) {
|
||||
curl_setopt($ch, CURLOPT_INTERFACE, $ip);
|
||||
}
|
||||
|
||||
// request timeout
|
||||
if ($timeout = $this->request->getConfig('timeout')) {
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||||
}
|
||||
|
||||
// set HTTP version
|
||||
switch ($this->request->getConfig('protocol_version')) {
|
||||
case '1.0':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
break;
|
||||
case '1.1':
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
}
|
||||
|
||||
// set request method
|
||||
switch ($this->request->getMethod()) {
|
||||
case HTTP_Request2::METHOD_GET:
|
||||
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_POST:
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_HEAD:
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
break;
|
||||
case HTTP_Request2::METHOD_PUT:
|
||||
curl_setopt($ch, CURLOPT_UPLOAD, true);
|
||||
break;
|
||||
default:
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod());
|
||||
}
|
||||
|
||||
// set proxy, if needed
|
||||
if ($host = $this->request->getConfig('proxy_host')) {
|
||||
if (!($port = $this->request->getConfig('proxy_port'))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port);
|
||||
if ($user = $this->request->getConfig('proxy_user')) {
|
||||
curl_setopt(
|
||||
$ch, CURLOPT_PROXYUSERPWD,
|
||||
$user . ':' . $this->request->getConfig('proxy_password')
|
||||
);
|
||||
switch ($this->request->getConfig('proxy_auth_scheme')) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
if ($type = $this->request->getConfig('proxy_type')) {
|
||||
switch ($type) {
|
||||
case 'http':
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
break;
|
||||
case 'socks5':
|
||||
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
break;
|
||||
default:
|
||||
throw new HTTP_Request2_NotImplementedException(
|
||||
"Proxy type '{$type}' is not supported"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set authentication data
|
||||
if ($auth = $this->request->getAuth()) {
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']);
|
||||
switch ($auth['scheme']) {
|
||||
case HTTP_Request2::AUTH_BASIC:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
break;
|
||||
case HTTP_Request2::AUTH_DIGEST:
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
}
|
||||
}
|
||||
|
||||
// set SSL options
|
||||
foreach ($this->request->getConfig() as $name => $value) {
|
||||
if ('ssl_verify_host' == $name && null !== $value) {
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0);
|
||||
} elseif (isset(self::$sslContextMap[$name]) && null !== $value) {
|
||||
curl_setopt($ch, self::$sslContextMap[$name], $value);
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->request->getHeaders();
|
||||
// make cURL automagically send proper header
|
||||
if (!isset($headers['accept-encoding'])) {
|
||||
$headers['accept-encoding'] = '';
|
||||
}
|
||||
|
||||
if (($jar = $this->request->getCookieJar())
|
||||
&& ($cookies = $jar->getMatching($this->request->getUrl(), true))
|
||||
) {
|
||||
$headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies;
|
||||
}
|
||||
|
||||
// set headers having special cURL keys
|
||||
foreach (self::$headerMap as $name => $option) {
|
||||
if (isset($headers[$name])) {
|
||||
curl_setopt($ch, $option, $headers[$name]);
|
||||
unset($headers[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->calculateRequestLength($headers);
|
||||
if (isset($headers['content-length']) || isset($headers['transfer-encoding'])) {
|
||||
$this->workaroundPhpBug47204($ch, $headers);
|
||||
}
|
||||
|
||||
// set headers not having special keys
|
||||
$headersFmt = array();
|
||||
foreach ($headers as $name => $value) {
|
||||
$canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
|
||||
$headersFmt[] = $canonicalName . ': ' . $value;
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt);
|
||||
|
||||
return $ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for PHP bug #47204 that prevents rewinding request body
|
||||
*
|
||||
* The workaround consists of reading the entire request body into memory
|
||||
* and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large
|
||||
* file uploads, use Socket adapter instead.
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param array &$headers Request headers
|
||||
*/
|
||||
protected function workaroundPhpBug47204($ch, &$headers)
|
||||
{
|
||||
// no redirects, no digest auth -> probably no rewind needed
|
||||
// also apply workaround only for POSTs, othrerwise we get
|
||||
// https://pear.php.net/bugs/bug.php?id=20440 for PUTs
|
||||
if (!$this->request->getConfig('follow_redirects')
|
||||
&& (!($auth = $this->request->getAuth())
|
||||
|| HTTP_Request2::AUTH_DIGEST != $auth['scheme'])
|
||||
|| HTTP_Request2::METHOD_POST !== $this->request->getMethod()
|
||||
) {
|
||||
curl_setopt($ch, CURLOPT_READFUNCTION, array($this, 'callbackReadBody'));
|
||||
|
||||
} else {
|
||||
// rewind may be needed, read the whole body into memory
|
||||
if ($this->requestBody instanceof HTTP_Request2_MultipartBody) {
|
||||
$this->requestBody = $this->requestBody->__toString();
|
||||
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$fp = $this->requestBody;
|
||||
$this->requestBody = '';
|
||||
while (!feof($fp)) {
|
||||
$this->requestBody .= fread($fp, 16384);
|
||||
}
|
||||
}
|
||||
// curl hangs up if content-length is present
|
||||
unset($headers['content-length']);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for reading the request body
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param resource $fd file descriptor (not used)
|
||||
* @param integer $length maximum length of data to return
|
||||
*
|
||||
* @return string part of the request body, up to $length bytes
|
||||
*/
|
||||
protected function callbackReadBody($ch, $fd, $length)
|
||||
{
|
||||
if (!$this->eventSentHeaders) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
$this->eventSentHeaders = true;
|
||||
}
|
||||
if (in_array($this->request->getMethod(), self::$bodyDisallowed)
|
||||
|| 0 == $this->contentLength || $this->position >= $this->contentLength
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($this->requestBody)) {
|
||||
$string = substr($this->requestBody, $this->position, $length);
|
||||
} elseif (is_resource($this->requestBody)) {
|
||||
$string = fread($this->requestBody, $length);
|
||||
} else {
|
||||
$string = $this->requestBody->read($length);
|
||||
}
|
||||
$this->request->setLastEvent('sentBodyPart', strlen($string));
|
||||
$this->position += strlen($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response headers
|
||||
*
|
||||
* @param resource $ch cURL handle
|
||||
* @param string $string response header (with trailing CRLF)
|
||||
*
|
||||
* @return integer number of bytes saved
|
||||
* @see HTTP_Request2_Response::parseHeaderLine()
|
||||
*/
|
||||
protected function callbackWriteHeader($ch, $string)
|
||||
{
|
||||
if (!$this->eventSentHeaders
|
||||
// we may receive a second set of headers if doing e.g. digest auth
|
||||
// but don't bother with 100-Continue responses (bug #15785)
|
||||
|| $this->eventReceivedHeaders && $this->response->getStatus() >= 200
|
||||
) {
|
||||
$this->request->setLastEvent(
|
||||
'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT)
|
||||
);
|
||||
}
|
||||
if (!$this->eventSentBody) {
|
||||
$upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD);
|
||||
// if body wasn't read by the callback, send event with total body size
|
||||
if ($upload > $this->position) {
|
||||
$this->request->setLastEvent(
|
||||
'sentBodyPart', $upload - $this->position
|
||||
);
|
||||
}
|
||||
if ($upload > 0) {
|
||||
$this->request->setLastEvent('sentBody', $upload);
|
||||
}
|
||||
}
|
||||
$this->eventSentHeaders = true;
|
||||
$this->eventSentBody = true;
|
||||
|
||||
if ($this->eventReceivedHeaders || empty($this->response)) {
|
||||
$this->eventReceivedHeaders = false;
|
||||
$this->response = new HTTP_Request2_Response(
|
||||
$string, false, curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)
|
||||
);
|
||||
|
||||
} else {
|
||||
$this->response->parseHeaderLine($string);
|
||||
if ('' == trim($string)) {
|
||||
// don't bother with 100-Continue responses (bug #15785)
|
||||
if (200 <= $this->response->getStatus()) {
|
||||
$this->request->setLastEvent('receivedHeaders', $this->response);
|
||||
}
|
||||
|
||||
if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) {
|
||||
$redirectUrl = new Net_URL2($this->response->getHeader('location'));
|
||||
|
||||
// for versions lower than 5.2.10, check the redirection URL protocol
|
||||
if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute()
|
||||
&& !in_array($redirectUrl->getScheme(), array('http', 'https'))
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($jar = $this->request->getCookieJar()) {
|
||||
$jar->addCookiesFromResponse($this->response);
|
||||
if (!$redirectUrl->isAbsolute()) {
|
||||
$redirectUrl = $this->request->getUrl()->resolve($redirectUrl);
|
||||
}
|
||||
if ($cookies = $jar->getMatching($redirectUrl, true)) {
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->eventReceivedHeaders = true;
|
||||
$this->eventSentBody = false;
|
||||
}
|
||||
}
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function called by cURL for saving the response body
|
||||
*
|
||||
* @param resource $ch cURL handle (not used)
|
||||
* @param string $string part of the response body
|
||||
*
|
||||
* @return integer number of bytes saved
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @see HTTP_Request2_Response::appendBody()
|
||||
*/
|
||||
protected function callbackWriteBody($ch, $string)
|
||||
{
|
||||
// cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if
|
||||
// response doesn't start with proper HTTP status line (see bug #15716)
|
||||
if (empty($this->response)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Malformed response: {$string}",
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
if ($this->request->getConfig('store_body')) {
|
||||
$this->response->appendBody($string);
|
||||
}
|
||||
$this->request->setLastEvent('receivedBodyPart', $string);
|
||||
return strlen($string);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for HTTP_Request2 adapters
|
||||
*/
|
||||
require_once 'HTTP/Request2/Adapter.php';
|
||||
|
||||
/**
|
||||
* Mock adapter intended for testing
|
||||
*
|
||||
* Can be used to test applications depending on HTTP_Request2 package without
|
||||
* actually performing any HTTP requests. This adapter will return responses
|
||||
* previously added via addResponse()
|
||||
* <code>
|
||||
* $mock = new HTTP_Request2_Adapter_Mock();
|
||||
* $mock->addResponse("HTTP/1.1 ... ");
|
||||
*
|
||||
* $request = new HTTP_Request2();
|
||||
* $request->setAdapter($mock);
|
||||
*
|
||||
* // This will return the response set above
|
||||
* $response = $req->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter
|
||||
{
|
||||
/**
|
||||
* A queue of responses to be returned by sendRequest()
|
||||
* @var array
|
||||
*/
|
||||
protected $responses = array();
|
||||
|
||||
/**
|
||||
* Returns the next response from the queue built by addResponse()
|
||||
*
|
||||
* Only responses without explicit URLs or with URLs equal to request URL
|
||||
* will be considered. If matching response is not found or the queue is
|
||||
* empty then default empty response with status 400 will be returned,
|
||||
* if an Exception object was added to the queue it will be thrown.
|
||||
*
|
||||
* @param HTTP_Request2 $request HTTP request message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendRequest(HTTP_Request2 $request)
|
||||
{
|
||||
$requestUrl = (string)$request->getUrl();
|
||||
$response = null;
|
||||
foreach ($this->responses as $k => $v) {
|
||||
if (!$v[1] || $requestUrl == $v[1]) {
|
||||
$response = $v[0];
|
||||
array_splice($this->responses, $k, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$response) {
|
||||
return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n");
|
||||
|
||||
} elseif ($response instanceof HTTP_Request2_Response) {
|
||||
return $response;
|
||||
|
||||
} else {
|
||||
// rethrow the exception
|
||||
$class = get_class($response);
|
||||
$message = $response->getMessage();
|
||||
$code = $response->getCode();
|
||||
throw new $class($message, $code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds response to the queue
|
||||
*
|
||||
* @param mixed $response either a string, a pointer to an open file,
|
||||
* an instance of HTTP_Request2_Response or Exception
|
||||
* @param string $url A request URL this response should be valid for
|
||||
* (see {@link http://pear.php.net/bugs/bug.php?id=19276})
|
||||
*
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function addResponse($response, $url = null)
|
||||
{
|
||||
if (is_string($response)) {
|
||||
$response = self::createResponseFromString($response);
|
||||
} elseif (is_resource($response)) {
|
||||
$response = self::createResponseFromFile($response);
|
||||
} elseif (!$response instanceof HTTP_Request2_Response &&
|
||||
!$response instanceof Exception
|
||||
) {
|
||||
throw new HTTP_Request2_Exception('Parameter is not a valid response');
|
||||
}
|
||||
$this->responses[] = array($response, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a string
|
||||
*
|
||||
* @param string $str string containing HTTP response message
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromString($str)
|
||||
{
|
||||
$parts = preg_split('!(\r?\n){2}!m', $str, 2);
|
||||
$headerLines = explode("\n", $parts[0]);
|
||||
$response = new HTTP_Request2_Response(array_shift($headerLines));
|
||||
foreach ($headerLines as $headerLine) {
|
||||
$response->parseHeaderLine($headerLine);
|
||||
}
|
||||
$response->parseHeaderLine('');
|
||||
if (isset($parts[1])) {
|
||||
$response->appendBody($parts[1]);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP_Request2_Response object from a file
|
||||
*
|
||||
* @param resource $fp file pointer returned by fopen()
|
||||
*
|
||||
* @return HTTP_Request2_Response
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public static function createResponseFromFile($fp)
|
||||
{
|
||||
$response = new HTTP_Request2_Response(fgets($fp));
|
||||
do {
|
||||
$headerLine = fgets($fp);
|
||||
$response->parseHeaderLine($headerLine);
|
||||
} while ('' != trim($headerLine));
|
||||
|
||||
while (!feof($fp)) {
|
||||
$response->appendBody(fread($fp, 8192));
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,547 @@
|
||||
<?php
|
||||
/**
|
||||
* Stores cookies and passes them between HTTP requests
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Class representing a HTTP request message */
|
||||
require_once 'HTTP/Request2.php';
|
||||
|
||||
/**
|
||||
* Stores cookies and passes them between HTTP requests
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_CookieJar implements Serializable
|
||||
{
|
||||
/**
|
||||
* Array of stored cookies
|
||||
*
|
||||
* The array is indexed by domain, path and cookie name
|
||||
* .example.com
|
||||
* /
|
||||
* some_cookie => cookie data
|
||||
* /subdir
|
||||
* other_cookie => cookie data
|
||||
* .example.org
|
||||
* ...
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Whether session cookies should be serialized when serializing the jar
|
||||
* @var bool
|
||||
*/
|
||||
protected $serializeSession = false;
|
||||
|
||||
/**
|
||||
* Whether Public Suffix List should be used for domain matching
|
||||
* @var bool
|
||||
*/
|
||||
protected $useList = true;
|
||||
|
||||
/**
|
||||
* Whether an attempt to store an invalid cookie should be ignored, rather than cause an Exception
|
||||
* @var bool
|
||||
*/
|
||||
protected $ignoreInvalid = false;
|
||||
|
||||
/**
|
||||
* Array with Public Suffix List data
|
||||
* @var array
|
||||
* @link http://publicsuffix.org/
|
||||
*/
|
||||
protected static $psl = array();
|
||||
|
||||
/**
|
||||
* Class constructor, sets various options
|
||||
*
|
||||
* @param bool $serializeSessionCookies Controls serializing session cookies,
|
||||
* see {@link serializeSessionCookies()}
|
||||
* @param bool $usePublicSuffixList Controls using Public Suffix List,
|
||||
* see {@link usePublicSuffixList()}
|
||||
* @param bool $ignoreInvalidCookies Whether invalid cookies should be ignored,
|
||||
* see {@link ignoreInvalidCookies()}
|
||||
*/
|
||||
public function __construct(
|
||||
$serializeSessionCookies = false, $usePublicSuffixList = true,
|
||||
$ignoreInvalidCookies = false
|
||||
) {
|
||||
$this->serializeSessionCookies($serializeSessionCookies);
|
||||
$this->usePublicSuffixList($usePublicSuffixList);
|
||||
$this->ignoreInvalidCookies($ignoreInvalidCookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current time formatted in ISO-8601 at UTC timezone
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function now()
|
||||
{
|
||||
$dt = new DateTime();
|
||||
$dt->setTimezone(new DateTimeZone('UTC'));
|
||||
return $dt->format(DateTime::ISO8601);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks cookie array for correctness, possibly updating its 'domain', 'path' and 'expires' fields
|
||||
*
|
||||
* The checks are as follows:
|
||||
* - cookie array should contain 'name' and 'value' fields;
|
||||
* - name and value should not contain disallowed symbols;
|
||||
* - 'expires' should be either empty parseable by DateTime;
|
||||
* - 'domain' and 'path' should be either not empty or an URL where
|
||||
* cookie was set should be provided.
|
||||
* - if $setter is provided, then document at that URL should be allowed
|
||||
* to set a cookie for that 'domain'. If $setter is not provided,
|
||||
* then no domain checks will be made.
|
||||
*
|
||||
* 'expires' field will be converted to ISO8601 format from COOKIE format,
|
||||
* 'domain' and 'path' will be set from setter URL if empty.
|
||||
*
|
||||
* @param array $cookie cookie data, as returned by
|
||||
* {@link HTTP_Request2_Response::getCookies()}
|
||||
* @param Net_URL2 $setter URL of the document that sent Set-Cookie header
|
||||
*
|
||||
* @return array Updated cookie array
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null)
|
||||
{
|
||||
if ($missing = array_diff(array('name', 'value'), array_keys($cookie))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Cookie array should contain 'name' and 'value' fields",
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['name'])) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Invalid cookie name: '{$cookie['name']}'",
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT
|
||||
);
|
||||
}
|
||||
if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['value'])) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Invalid cookie value: '{$cookie['value']}'",
|
||||
HTTP_Request2_Exception::INVALID_ARGUMENT
|
||||
);
|
||||
}
|
||||
$cookie += array('domain' => '', 'path' => '', 'expires' => null, 'secure' => false);
|
||||
|
||||
// Need ISO-8601 date @ UTC timezone
|
||||
if (!empty($cookie['expires'])
|
||||
&& !preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+0000$/', $cookie['expires'])
|
||||
) {
|
||||
try {
|
||||
$dt = new DateTime($cookie['expires']);
|
||||
$dt->setTimezone(new DateTimeZone('UTC'));
|
||||
$cookie['expires'] = $dt->format(DateTime::ISO8601);
|
||||
} catch (Exception $e) {
|
||||
throw new HTTP_Request2_LogicException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($cookie['domain']) || empty($cookie['path'])) {
|
||||
if (!$setter) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Cookie misses domain and/or path component, cookie setter URL needed',
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
if (empty($cookie['domain'])) {
|
||||
if ($host = $setter->getHost()) {
|
||||
$cookie['domain'] = $host;
|
||||
} else {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Setter URL does not contain host part, can\'t set cookie domain',
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
}
|
||||
if (empty($cookie['path'])) {
|
||||
$path = $setter->getPath();
|
||||
$cookie['path'] = empty($path)? '/': substr($path, 0, strrpos($path, '/') + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ($setter && !$this->domainMatch($setter->getHost(), $cookie['domain'])) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Domain " . $setter->getHost() . " cannot set cookies for "
|
||||
. $cookie['domain']
|
||||
);
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a cookie in the jar
|
||||
*
|
||||
* @param array $cookie cookie data, as returned by
|
||||
* {@link HTTP_Request2_Response::getCookies()}
|
||||
* @param Net_URL2 $setter URL of the document that sent Set-Cookie header
|
||||
*
|
||||
* @return bool whether the cookie was successfully stored
|
||||
* @throws HTTP_Request2_Exception
|
||||
*/
|
||||
public function store(array $cookie, Net_URL2 $setter = null)
|
||||
{
|
||||
try {
|
||||
$cookie = $this->checkAndUpdateFields($cookie, $setter);
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
if ($this->ignoreInvalid) {
|
||||
return false;
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($cookie['value'])
|
||||
&& (is_null($cookie['expires']) || $cookie['expires'] > $this->now())
|
||||
) {
|
||||
if (!isset($this->cookies[$cookie['domain']])) {
|
||||
$this->cookies[$cookie['domain']] = array();
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
|
||||
$this->cookies[$cookie['domain']][$cookie['path']] = array();
|
||||
}
|
||||
$this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
|
||||
|
||||
} elseif (isset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']])) {
|
||||
unset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds cookies set in HTTP response to the jar
|
||||
*
|
||||
* @param HTTP_Request2_Response $response HTTP response message
|
||||
* @param Net_URL2 $setter original request URL, needed for
|
||||
* setting default domain/path. If not given,
|
||||
* effective URL from response will be used.
|
||||
*
|
||||
* @return bool whether all cookies were successfully stored
|
||||
* @throws HTTP_Request2_LogicException
|
||||
*/
|
||||
public function addCookiesFromResponse(HTTP_Request2_Response $response, Net_URL2 $setter = null)
|
||||
{
|
||||
if (null === $setter) {
|
||||
if (!($effectiveUrl = $response->getEffectiveUrl())) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Response URL required for adding cookies from response',
|
||||
HTTP_Request2_Exception::MISSING_VALUE
|
||||
);
|
||||
}
|
||||
$setter = new Net_URL2($effectiveUrl);
|
||||
}
|
||||
|
||||
$success = true;
|
||||
foreach ($response->getCookies() as $cookie) {
|
||||
$success = $this->store($cookie, $setter) && $success;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cookies matching a given request URL
|
||||
*
|
||||
* The following checks are made:
|
||||
* - cookie domain should match request host
|
||||
* - cookie path should be a prefix for request path
|
||||
* - 'secure' cookies will only be sent for HTTPS requests
|
||||
*
|
||||
* @param Net_URL2 $url Request url
|
||||
* @param bool $asString Whether to return cookies as string for "Cookie: " header
|
||||
*
|
||||
* @return array|string Matching cookies
|
||||
*/
|
||||
public function getMatching(Net_URL2 $url, $asString = false)
|
||||
{
|
||||
$host = $url->getHost();
|
||||
$path = $url->getPath();
|
||||
$secure = 0 == strcasecmp($url->getScheme(), 'https');
|
||||
|
||||
$matched = $ret = array();
|
||||
foreach (array_keys($this->cookies) as $domain) {
|
||||
if ($this->domainMatch($host, $domain)) {
|
||||
foreach (array_keys($this->cookies[$domain]) as $cPath) {
|
||||
if (0 === strpos($path, $cPath)) {
|
||||
foreach ($this->cookies[$domain][$cPath] as $name => $cookie) {
|
||||
if (!$cookie['secure'] || $secure) {
|
||||
$matched[$name][strlen($cookie['path'])] = $cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($matched as $cookies) {
|
||||
krsort($cookies);
|
||||
$ret = array_merge($ret, $cookies);
|
||||
}
|
||||
if (!$asString) {
|
||||
return $ret;
|
||||
} else {
|
||||
$str = '';
|
||||
foreach ($ret as $c) {
|
||||
$str .= (empty($str)? '': '; ') . $c['name'] . '=' . $c['value'];
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all cookies stored in a jar
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
$cookies = array();
|
||||
foreach (array_keys($this->cookies) as $domain) {
|
||||
foreach (array_keys($this->cookies[$domain]) as $path) {
|
||||
foreach ($this->cookies[$domain][$path] as $name => $cookie) {
|
||||
$cookies[] = $cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether session cookies should be serialized when serializing the jar
|
||||
*
|
||||
* @param boolean $serialize serialize?
|
||||
*/
|
||||
public function serializeSessionCookies($serialize)
|
||||
{
|
||||
$this->serializeSession = (bool)$serialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether invalid cookies should be silently ignored or cause an Exception
|
||||
*
|
||||
* @param boolean $ignore ignore?
|
||||
* @link http://pear.php.net/bugs/bug.php?id=19937
|
||||
* @link http://pear.php.net/bugs/bug.php?id=20401
|
||||
*/
|
||||
public function ignoreInvalidCookies($ignore)
|
||||
{
|
||||
$this->ignoreInvalid = (bool)$ignore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether Public Suffix List should be used for restricting cookie-setting
|
||||
*
|
||||
* Without PSL {@link domainMatch()} will only prevent setting cookies for
|
||||
* top-level domains like '.com' or '.org'. However, it will not prevent
|
||||
* setting a cookie for '.co.uk' even though only third-level registrations
|
||||
* are possible in .uk domain.
|
||||
*
|
||||
* With the List it is possible to find the highest level at which a domain
|
||||
* may be registered for a particular top-level domain and consequently
|
||||
* prevent cookies set for '.co.uk' or '.msk.ru'. The same list is used by
|
||||
* Firefox, Chrome and Opera browsers to restrict cookie setting.
|
||||
*
|
||||
* Note that PSL is licensed differently to HTTP_Request2 package (refer to
|
||||
* the license information in public-suffix-list.php), so you can disable
|
||||
* its use if this is an issue for you.
|
||||
*
|
||||
* @param boolean $useList use the list?
|
||||
*
|
||||
* @link http://publicsuffix.org/learn/
|
||||
*/
|
||||
public function usePublicSuffixList($useList)
|
||||
{
|
||||
$this->useList = (bool)$useList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string representation of object
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see Serializable::serialize()
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
$cookies = $this->getAll();
|
||||
if (!$this->serializeSession) {
|
||||
for ($i = count($cookies) - 1; $i >= 0; $i--) {
|
||||
if (empty($cookies[$i]['expires'])) {
|
||||
unset($cookies[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return serialize(array(
|
||||
'cookies' => $cookies,
|
||||
'serializeSession' => $this->serializeSession,
|
||||
'useList' => $this->useList,
|
||||
'ignoreInvalid' => $this->ignoreInvalid
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the object from serialized string
|
||||
*
|
||||
* @param string $serialized string representation
|
||||
*
|
||||
* @see Serializable::unserialize()
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
$now = $this->now();
|
||||
$this->serializeSessionCookies($data['serializeSession']);
|
||||
$this->usePublicSuffixList($data['useList']);
|
||||
if (array_key_exists('ignoreInvalid', $data)) {
|
||||
$this->ignoreInvalidCookies($data['ignoreInvalid']);
|
||||
}
|
||||
foreach ($data['cookies'] as $cookie) {
|
||||
if (!empty($cookie['expires']) && $cookie['expires'] <= $now) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']])) {
|
||||
$this->cookies[$cookie['domain']] = array();
|
||||
}
|
||||
if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) {
|
||||
$this->cookies[$cookie['domain']][$cookie['path']] = array();
|
||||
}
|
||||
$this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a cookie domain matches a request host.
|
||||
*
|
||||
* The method is used by {@link store()} to check for whether a document
|
||||
* at given URL can set a cookie with a given domain attribute and by
|
||||
* {@link getMatching()} to find cookies matching the request URL.
|
||||
*
|
||||
* @param string $requestHost request host
|
||||
* @param string $cookieDomain cookie domain
|
||||
*
|
||||
* @return bool match success
|
||||
*/
|
||||
public function domainMatch($requestHost, $cookieDomain)
|
||||
{
|
||||
if ($requestHost == $cookieDomain) {
|
||||
return true;
|
||||
}
|
||||
// IP address, we require exact match
|
||||
if (preg_match('/^(?:\d{1,3}\.){3}\d{1,3}$/', $requestHost)) {
|
||||
return false;
|
||||
}
|
||||
if ('.' != $cookieDomain[0]) {
|
||||
$cookieDomain = '.' . $cookieDomain;
|
||||
}
|
||||
// prevents setting cookies for '.com' and similar domains
|
||||
if (!$this->useList && substr_count($cookieDomain, '.') < 2
|
||||
|| $this->useList && !self::getRegisteredDomain($cookieDomain)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes subdomains to get the registered domain (the first after top-level)
|
||||
*
|
||||
* The method will check Public Suffix List to find out where top-level
|
||||
* domain ends and registered domain starts. It will remove domain parts
|
||||
* to the left of registered one.
|
||||
*
|
||||
* @param string $domain domain name
|
||||
*
|
||||
* @return string|bool registered domain, will return false if $domain is
|
||||
* either invalid or a TLD itself
|
||||
*/
|
||||
public static function getRegisteredDomain($domain)
|
||||
{
|
||||
$domainParts = explode('.', ltrim($domain, '.'));
|
||||
|
||||
// load the list if needed
|
||||
if (empty(self::$psl)) {
|
||||
$path = '@data_dir@' . DIRECTORY_SEPARATOR . 'HTTP_Request2';
|
||||
if (0 === strpos($path, '@' . 'data_dir@')) {
|
||||
$path = realpath(
|
||||
dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'
|
||||
. DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data'
|
||||
);
|
||||
}
|
||||
self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php';
|
||||
}
|
||||
|
||||
if (!($result = self::checkDomainsList($domainParts, self::$psl))) {
|
||||
// known TLD, invalid domain name
|
||||
return false;
|
||||
}
|
||||
|
||||
// unknown TLD
|
||||
if (!strpos($result, '.')) {
|
||||
// fallback to checking that domain "has at least two dots"
|
||||
if (2 > ($count = count($domainParts))) {
|
||||
return false;
|
||||
}
|
||||
return $domainParts[$count - 2] . '.' . $domainParts[$count - 1];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper method for {@link getRegisteredDomain()}
|
||||
*
|
||||
* @param array $domainParts remaining domain parts
|
||||
* @param mixed $listNode node in {@link HTTP_Request2_CookieJar::$psl} to check
|
||||
*
|
||||
* @return string|null concatenated domain parts, null in case of error
|
||||
*/
|
||||
protected static function checkDomainsList(array $domainParts, $listNode)
|
||||
{
|
||||
$sub = array_pop($domainParts);
|
||||
$result = null;
|
||||
|
||||
if (!is_array($listNode) || is_null($sub)
|
||||
|| array_key_exists('!' . $sub, $listNode)
|
||||
) {
|
||||
return $sub;
|
||||
|
||||
} elseif (array_key_exists($sub, $listNode)) {
|
||||
$result = self::checkDomainsList($domainParts, $listNode[$sub]);
|
||||
|
||||
} elseif (array_key_exists('*', $listNode)) {
|
||||
$result = self::checkDomainsList($domainParts, $listNode['*']);
|
||||
|
||||
} else {
|
||||
return $sub;
|
||||
}
|
||||
|
||||
return (strlen($result) > 0) ? ($result . '.' . $sub) : null;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception classes for HTTP_Request2 package
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for exceptions in PEAR
|
||||
*/
|
||||
require_once 'PEAR/Exception.php';
|
||||
|
||||
/**
|
||||
* Base exception class for HTTP_Request2 package
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=132
|
||||
*/
|
||||
class HTTP_Request2_Exception extends PEAR_Exception
|
||||
{
|
||||
/** An invalid argument was passed to a method */
|
||||
const INVALID_ARGUMENT = 1;
|
||||
/** Some required value was not available */
|
||||
const MISSING_VALUE = 2;
|
||||
/** Request cannot be processed due to errors in PHP configuration */
|
||||
const MISCONFIGURATION = 3;
|
||||
/** Error reading the local file */
|
||||
const READ_ERROR = 4;
|
||||
|
||||
/** Server returned a response that does not conform to HTTP protocol */
|
||||
const MALFORMED_RESPONSE = 10;
|
||||
/** Failure decoding Content-Encoding or Transfer-Encoding of response */
|
||||
const DECODE_ERROR = 20;
|
||||
/** Operation timed out */
|
||||
const TIMEOUT = 30;
|
||||
/** Number of redirects exceeded 'max_redirects' configuration parameter */
|
||||
const TOO_MANY_REDIRECTS = 40;
|
||||
/** Redirect to a protocol other than http(s):// */
|
||||
const NON_HTTP_REDIRECT = 50;
|
||||
|
||||
/**
|
||||
* Native error code
|
||||
* @var int
|
||||
*/
|
||||
private $_nativeCode;
|
||||
|
||||
/**
|
||||
* Constructor, can set package error code and native error code
|
||||
*
|
||||
* @param string $message exception message
|
||||
* @param int $code package error code, one of class constants
|
||||
* @param int $nativeCode error code from underlying PHP extension
|
||||
*/
|
||||
public function __construct($message = null, $code = null, $nativeCode = null)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
$this->_nativeCode = $nativeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns error code produced by underlying PHP extension
|
||||
*
|
||||
* For Socket Adapter this may contain error number returned by
|
||||
* stream_socket_client(), for Curl Adapter this will contain error number
|
||||
* returned by curl_errno()
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getNativeCode()
|
||||
{
|
||||
return $this->_nativeCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown in case of missing features
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception that represents error in the program logic
|
||||
*
|
||||
* This exception usually implies a programmer's error, like passing invalid
|
||||
* data to methods or trying to use PHP extensions that weren't installed or
|
||||
* enabled. Usually exceptions of this kind will be thrown before request even
|
||||
* starts.
|
||||
*
|
||||
* The exception will usually contain a package error code.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_LogicException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when connection to a web or proxy server fails
|
||||
*
|
||||
* The exception will not contain a package error code, but will contain
|
||||
* native error code, as returned by stream_socket_client() or curl_errno().
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when sending or receiving HTTP message fails
|
||||
*
|
||||
* The exception may contain both package error code and native error code.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_MessageException extends HTTP_Request2_Exception
|
||||
{
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper class for building multipart/form-data request body
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Exception class for HTTP_Request2 package */
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class for building multipart/form-data request body
|
||||
*
|
||||
* The class helps to reduce memory consumption by streaming large file uploads
|
||||
* from disk, it also allows monitoring of upload progress (see request #7630)
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://tools.ietf.org/html/rfc1867
|
||||
*/
|
||||
class HTTP_Request2_MultipartBody
|
||||
{
|
||||
/**
|
||||
* MIME boundary
|
||||
* @var string
|
||||
*/
|
||||
private $_boundary;
|
||||
|
||||
/**
|
||||
* Form parameters added via {@link HTTP_Request2::addPostParameter()}
|
||||
* @var array
|
||||
*/
|
||||
private $_params = array();
|
||||
|
||||
/**
|
||||
* File uploads added via {@link HTTP_Request2::addUpload()}
|
||||
* @var array
|
||||
*/
|
||||
private $_uploads = array();
|
||||
|
||||
/**
|
||||
* Header for parts with parameters
|
||||
* @var string
|
||||
*/
|
||||
private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Header for parts with uploads
|
||||
* @var string
|
||||
*/
|
||||
private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n";
|
||||
|
||||
/**
|
||||
* Current position in parameter and upload arrays
|
||||
*
|
||||
* First number is index of "current" part, second number is position within
|
||||
* "current" part
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_pos = array(0, 0);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor. Sets the arrays with POST data.
|
||||
*
|
||||
* @param array $params values of form fields set via
|
||||
* {@link HTTP_Request2::addPostParameter()}
|
||||
* @param array $uploads file uploads set via
|
||||
* {@link HTTP_Request2::addUpload()}
|
||||
* @param bool $useBrackets whether to append brackets to array variable names
|
||||
*/
|
||||
public function __construct(array $params, array $uploads, $useBrackets = true)
|
||||
{
|
||||
$this->_params = self::_flattenArray('', $params, $useBrackets);
|
||||
foreach ($uploads as $fieldName => $f) {
|
||||
if (!is_array($f['fp'])) {
|
||||
$this->_uploads[] = $f + array('name' => $fieldName);
|
||||
} else {
|
||||
for ($i = 0; $i < count($f['fp']); $i++) {
|
||||
$upload = array(
|
||||
'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName)
|
||||
);
|
||||
foreach (array('fp', 'filename', 'size', 'type') as $key) {
|
||||
$upload[$key] = $f[$key][$i];
|
||||
}
|
||||
$this->_uploads[] = $upload;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the body to use in Content-Length header
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLength()
|
||||
{
|
||||
$boundaryLength = strlen($this->getBoundary());
|
||||
$headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength;
|
||||
$headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength;
|
||||
$length = $boundaryLength + 6;
|
||||
foreach ($this->_params as $p) {
|
||||
$length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2;
|
||||
}
|
||||
foreach ($this->_uploads as $u) {
|
||||
$length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) +
|
||||
strlen($u['filename']) + $u['size'] + 2;
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boundary to use in Content-Type header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBoundary()
|
||||
{
|
||||
if (empty($this->_boundary)) {
|
||||
$this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime());
|
||||
}
|
||||
return $this->_boundary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next chunk of request body
|
||||
*
|
||||
* @param integer $length Number of bytes to read
|
||||
*
|
||||
* @return string Up to $length bytes of data, empty string if at end
|
||||
* @throws HTTP_Request2_LogicException
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
$ret = '';
|
||||
$boundary = $this->getBoundary();
|
||||
$paramCount = count($this->_params);
|
||||
$uploadCount = count($this->_uploads);
|
||||
while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) {
|
||||
$oldLength = $length;
|
||||
if ($this->_pos[0] < $paramCount) {
|
||||
$param = sprintf(
|
||||
$this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0]
|
||||
) . $this->_params[$this->_pos[0]][1] . "\r\n";
|
||||
$ret .= substr($param, $this->_pos[1], $length);
|
||||
$length -= min(strlen($param) - $this->_pos[1], $length);
|
||||
|
||||
} elseif ($this->_pos[0] < $paramCount + $uploadCount) {
|
||||
$pos = $this->_pos[0] - $paramCount;
|
||||
$header = sprintf(
|
||||
$this->_headerUpload, $boundary, $this->_uploads[$pos]['name'],
|
||||
$this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type']
|
||||
);
|
||||
if ($this->_pos[1] < strlen($header)) {
|
||||
$ret .= substr($header, $this->_pos[1], $length);
|
||||
$length -= min(strlen($header) - $this->_pos[1], $length);
|
||||
}
|
||||
$filePos = max(0, $this->_pos[1] - strlen($header));
|
||||
if ($filePos < $this->_uploads[$pos]['size']) {
|
||||
while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) {
|
||||
if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR
|
||||
);
|
||||
}
|
||||
$ret .= $chunk;
|
||||
$length -= strlen($chunk);
|
||||
}
|
||||
}
|
||||
if ($length > 0) {
|
||||
$start = $this->_pos[1] + ($oldLength - $length) -
|
||||
strlen($header) - $this->_uploads[$pos]['size'];
|
||||
$ret .= substr("\r\n", $start, $length);
|
||||
$length -= min(2 - $start, $length);
|
||||
}
|
||||
|
||||
} else {
|
||||
$closing = '--' . $boundary . "--\r\n";
|
||||
$ret .= substr($closing, $this->_pos[1], $length);
|
||||
$length -= min(strlen($closing) - $this->_pos[1], $length);
|
||||
}
|
||||
if ($length > 0) {
|
||||
$this->_pos = array($this->_pos[0] + 1, 0);
|
||||
} else {
|
||||
$this->_pos[1] += $oldLength;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current position to the start of the body
|
||||
*
|
||||
* This allows reusing the same body in another request
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->_pos = array(0, 0);
|
||||
foreach ($this->_uploads as $u) {
|
||||
rewind($u['fp']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body as string
|
||||
*
|
||||
* Note that it reads all file uploads into memory so it is a good idea not
|
||||
* to use this method with large file uploads and rely on read() instead.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$this->rewind();
|
||||
return $this->read($this->getLength());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to change the (probably multidimensional) associative array
|
||||
* into the simple one.
|
||||
*
|
||||
* @param string $name name for item
|
||||
* @param mixed $values item's values
|
||||
* @param bool $useBrackets whether to append [] to array variables' names
|
||||
*
|
||||
* @return array array with the following items: array('item name', 'item value');
|
||||
*/
|
||||
private static function _flattenArray($name, $values, $useBrackets)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
return array(array($name, $values));
|
||||
} else {
|
||||
$ret = array();
|
||||
foreach ($values as $k => $v) {
|
||||
if (empty($name)) {
|
||||
$newName = $k;
|
||||
} elseif ($useBrackets) {
|
||||
$newName = $name . '[' . $k . ']';
|
||||
} else {
|
||||
$newName = $name;
|
||||
}
|
||||
$ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets));
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* An observer useful for debugging / testing.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* A debug observer useful for debugging / testing.
|
||||
*
|
||||
* This observer logs to a log target data corresponding to the various request
|
||||
* and response events, it logs by default to php://output but can be configured
|
||||
* to log to a file or via the PEAR Log package.
|
||||
*
|
||||
* A simple example:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* $observer = new HTTP_Request2_Observer_Log();
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* A more complex example with PEAR Log:
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/Log.php';
|
||||
* require_once 'Log.php';
|
||||
*
|
||||
* $request = new HTTP_Request2('http://www.example.com');
|
||||
* // we want to log with PEAR log
|
||||
* $observer = new HTTP_Request2_Observer_Log(Log::factory('console'));
|
||||
*
|
||||
* // we only want to log received headers
|
||||
* $observer->events = array('receivedHeaders');
|
||||
*
|
||||
* $request->attach($observer);
|
||||
* $request->send();
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author David Jean Louis <izi@php.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Observer_Log implements SplObserver
|
||||
{
|
||||
// properties {{{
|
||||
|
||||
/**
|
||||
* The log target, it can be a a resource or a PEAR Log instance.
|
||||
*
|
||||
* @var resource|Log $target
|
||||
*/
|
||||
protected $target = null;
|
||||
|
||||
/**
|
||||
* The events to log.
|
||||
*
|
||||
* @var array $events
|
||||
*/
|
||||
public $events = array(
|
||||
'connect',
|
||||
'sentHeaders',
|
||||
'sentBody',
|
||||
'receivedHeaders',
|
||||
'receivedBody',
|
||||
'disconnect',
|
||||
);
|
||||
|
||||
// }}}
|
||||
// __construct() {{{
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param mixed $target Can be a file path (default: php://output), a resource,
|
||||
* or an instance of the PEAR Log class.
|
||||
* @param array $events Array of events to listen to (default: all events)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($target = 'php://output', array $events = array())
|
||||
{
|
||||
if (!empty($events)) {
|
||||
$this->events = $events;
|
||||
}
|
||||
if (is_resource($target) || $target instanceof Log) {
|
||||
$this->target = $target;
|
||||
} elseif (false === ($this->target = @fopen($target, 'ab'))) {
|
||||
throw new HTTP_Request2_Exception("Unable to open '{$target}'");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// update() {{{
|
||||
|
||||
/**
|
||||
* Called when the request notifies us of an event.
|
||||
*
|
||||
* @param HTTP_Request2 $subject The HTTP_Request2 instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function update(SplSubject $subject)
|
||||
{
|
||||
$event = $subject->getLastEvent();
|
||||
if (!in_array($event['name'], $this->events)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($event['name']) {
|
||||
case 'connect':
|
||||
$this->log('* Connected to ' . $event['data']);
|
||||
break;
|
||||
case 'sentHeaders':
|
||||
$headers = explode("\r\n", $event['data']);
|
||||
array_pop($headers);
|
||||
foreach ($headers as $header) {
|
||||
$this->log('> ' . $header);
|
||||
}
|
||||
break;
|
||||
case 'sentBody':
|
||||
$this->log('> ' . $event['data'] . ' byte(s) sent');
|
||||
break;
|
||||
case 'receivedHeaders':
|
||||
$this->log(sprintf(
|
||||
'< HTTP/%s %s %s', $event['data']->getVersion(),
|
||||
$event['data']->getStatus(), $event['data']->getReasonPhrase()
|
||||
));
|
||||
$headers = $event['data']->getHeader();
|
||||
foreach ($headers as $key => $val) {
|
||||
$this->log('< ' . $key . ': ' . $val);
|
||||
}
|
||||
$this->log('< ');
|
||||
break;
|
||||
case 'receivedBody':
|
||||
$this->log($event['data']->getBody());
|
||||
break;
|
||||
case 'disconnect':
|
||||
$this->log('* Disconnected');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// log() {{{
|
||||
|
||||
/**
|
||||
* Logs the given message to the configured target.
|
||||
*
|
||||
* @param string $message Message to display
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function log($message)
|
||||
{
|
||||
if ($this->target instanceof Log) {
|
||||
$this->target->debug($message);
|
||||
} elseif (is_resource($this->target)) {
|
||||
fwrite($this->target, $message . "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/**
|
||||
* An observer that saves response body to stream, possibly uncompressing it
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Delian Krustev <krustev@krustev.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
require_once 'HTTP/Request2/Response.php';
|
||||
|
||||
/**
|
||||
* An observer that saves response body to stream, possibly uncompressing it
|
||||
*
|
||||
* This Observer is written in compliment to pear's HTTP_Request2 in order to
|
||||
* avoid reading the whole response body in memory. Instead it writes the body
|
||||
* to a stream. If the body is transferred with content-encoding set to
|
||||
* "deflate" or "gzip" it is decoded on the fly.
|
||||
*
|
||||
* The constructor accepts an already opened (for write) stream (file_descriptor).
|
||||
* If the response is deflate/gzip encoded a "zlib.inflate" filter is applied
|
||||
* to the stream. When the body has been read from the request and written to
|
||||
* the stream ("receivedBody" event) the filter is removed from the stream.
|
||||
*
|
||||
* The "zlib.inflate" filter works fine with pure "deflate" encoding. It does
|
||||
* not understand the "deflate+zlib" and "gzip" headers though, so they have to
|
||||
* be removed prior to being passed to the stream. This is done in the "update"
|
||||
* method.
|
||||
*
|
||||
* It is also possible to limit the size of written extracted bytes by passing
|
||||
* "max_bytes" to the constructor. This is important because e.g. 1GB of
|
||||
* zeroes take about a MB when compressed.
|
||||
*
|
||||
* Exceptions are being thrown if data could not be written to the stream or
|
||||
* the written bytes have already exceeded the requested maximum. If the "gzip"
|
||||
* header is malformed or could not be parsed an exception will be thrown too.
|
||||
*
|
||||
* Example usage follows:
|
||||
*
|
||||
* <code>
|
||||
* require_once 'HTTP/Request2.php';
|
||||
* require_once 'HTTP/Request2/Observer/UncompressingDownload.php';
|
||||
*
|
||||
* #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html';
|
||||
* #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on';
|
||||
* $inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on&zlib=on';
|
||||
* #$outPath = "/dev/null";
|
||||
* $outPath = "delme";
|
||||
*
|
||||
* $stream = fopen($outPath, 'wb');
|
||||
* if (!$stream) {
|
||||
* throw new Exception('fopen failed');
|
||||
* }
|
||||
*
|
||||
* $request = new HTTP_Request2(
|
||||
* $inPath,
|
||||
* HTTP_Request2::METHOD_GET,
|
||||
* array(
|
||||
* 'store_body' => false,
|
||||
* 'connect_timeout' => 5,
|
||||
* 'timeout' => 10,
|
||||
* 'ssl_verify_peer' => true,
|
||||
* 'ssl_verify_host' => true,
|
||||
* 'ssl_cafile' => null,
|
||||
* 'ssl_capath' => '/etc/ssl/certs',
|
||||
* 'max_redirects' => 10,
|
||||
* 'follow_redirects' => true,
|
||||
* 'strict_redirects' => false
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* $observer = new HTTP_Request2_Observer_UncompressingDownload($stream, 9999999);
|
||||
* $request->attach($observer);
|
||||
*
|
||||
* $response = $request->send();
|
||||
*
|
||||
* fclose($stream);
|
||||
* echo "OK\n";
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Delian Krustev <krustev@krustev.net>
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
class HTTP_Request2_Observer_UncompressingDownload implements SplObserver
|
||||
{
|
||||
/**
|
||||
* The stream to write response body to
|
||||
* @var resource
|
||||
*/
|
||||
private $_stream;
|
||||
|
||||
/**
|
||||
* zlib.inflate filter possibly added to stream
|
||||
* @var resource
|
||||
*/
|
||||
private $_streamFilter;
|
||||
|
||||
/**
|
||||
* The value of response's Content-Encoding header
|
||||
* @var string
|
||||
*/
|
||||
private $_encoding;
|
||||
|
||||
/**
|
||||
* Whether the observer is still waiting for gzip/deflate header
|
||||
* @var bool
|
||||
*/
|
||||
private $_processingHeader = true;
|
||||
|
||||
/**
|
||||
* Starting position in the stream observer writes to
|
||||
* @var int
|
||||
*/
|
||||
private $_startPosition = 0;
|
||||
|
||||
/**
|
||||
* Maximum bytes to write
|
||||
* @var int|null
|
||||
*/
|
||||
private $_maxDownloadSize;
|
||||
|
||||
/**
|
||||
* Whether response being received is a redirect
|
||||
* @var bool
|
||||
*/
|
||||
private $_redirect = false;
|
||||
|
||||
/**
|
||||
* Accumulated body chunks that may contain (gzip) header
|
||||
* @var string
|
||||
*/
|
||||
private $_possibleHeader = '';
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* Note that there might be problems with max_bytes and files bigger
|
||||
* than 2 GB on 32bit platforms
|
||||
*
|
||||
* @param resource $stream a stream (or file descriptor) opened for writing.
|
||||
* @param int $maxDownloadSize maximum bytes to write
|
||||
*/
|
||||
public function __construct($stream, $maxDownloadSize = null)
|
||||
{
|
||||
$this->_stream = $stream;
|
||||
if ($maxDownloadSize) {
|
||||
$this->_maxDownloadSize = $maxDownloadSize;
|
||||
$this->_startPosition = ftell($this->_stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the request notifies us of an event.
|
||||
*
|
||||
* @param SplSubject $request The HTTP_Request2 instance
|
||||
*
|
||||
* @return void
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function update(SplSubject $request)
|
||||
{
|
||||
/* @var $request HTTP_Request2 */
|
||||
$event = $request->getLastEvent();
|
||||
$encoded = false;
|
||||
|
||||
/* @var $event['data'] HTTP_Request2_Response */
|
||||
switch ($event['name']) {
|
||||
case 'receivedHeaders':
|
||||
$this->_processingHeader = true;
|
||||
$this->_redirect = $event['data']->isRedirect();
|
||||
$this->_encoding = strtolower($event['data']->getHeader('content-encoding'));
|
||||
$this->_possibleHeader = '';
|
||||
break;
|
||||
|
||||
case 'receivedEncodedBodyPart':
|
||||
if (!$this->_streamFilter
|
||||
&& ($this->_encoding === 'deflate' || $this->_encoding === 'gzip')
|
||||
) {
|
||||
$this->_streamFilter = stream_filter_append(
|
||||
$this->_stream, 'zlib.inflate', STREAM_FILTER_WRITE
|
||||
);
|
||||
}
|
||||
$encoded = true;
|
||||
// fall-through is intentional
|
||||
|
||||
case 'receivedBodyPart':
|
||||
if ($this->_redirect) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$encoded || !$this->_processingHeader) {
|
||||
$bytes = fwrite($this->_stream, $event['data']);
|
||||
|
||||
} else {
|
||||
$offset = 0;
|
||||
$this->_possibleHeader .= $event['data'];
|
||||
if ('deflate' === $this->_encoding) {
|
||||
if (2 > strlen($this->_possibleHeader)) {
|
||||
break;
|
||||
}
|
||||
$header = unpack('n', substr($this->_possibleHeader, 0, 2));
|
||||
if (0 == $header[1] % 31) {
|
||||
$offset = 2;
|
||||
}
|
||||
|
||||
} elseif ('gzip' === $this->_encoding) {
|
||||
if (10 > strlen($this->_possibleHeader)) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
$offset = HTTP_Request2_Response::parseGzipHeader($this->_possibleHeader, false);
|
||||
|
||||
} catch (HTTP_Request2_MessageException $e) {
|
||||
// need more data?
|
||||
if (false !== strpos($e->getMessage(), 'data too short')) {
|
||||
break;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_processingHeader = false;
|
||||
$bytes = fwrite($this->_stream, substr($this->_possibleHeader, $offset));
|
||||
}
|
||||
|
||||
if (false === $bytes) {
|
||||
throw new HTTP_Request2_MessageException('fwrite failed.');
|
||||
}
|
||||
|
||||
if ($this->_maxDownloadSize
|
||||
&& ftell($this->_stream) - $this->_startPosition > $this->_maxDownloadSize
|
||||
) {
|
||||
throw new HTTP_Request2_MessageException(sprintf(
|
||||
'Body length limit (%d bytes) reached',
|
||||
$this->_maxDownloadSize
|
||||
));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'receivedBody':
|
||||
if ($this->_streamFilter) {
|
||||
stream_filter_remove($this->_streamFilter);
|
||||
$this->_streamFilter = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,680 @@
|
||||
<?php
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception class for HTTP_Request2 package
|
||||
*/
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Class representing a HTTP response
|
||||
*
|
||||
* The class is designed to be used in "streaming" scenario, building the
|
||||
* response as it is being received:
|
||||
* <code>
|
||||
* $statusLine = read_status_line();
|
||||
* $response = new HTTP_Request2_Response($statusLine);
|
||||
* do {
|
||||
* $headerLine = read_header_line();
|
||||
* $response->parseHeaderLine($headerLine);
|
||||
* } while ($headerLine != '');
|
||||
*
|
||||
* while ($chunk = read_body()) {
|
||||
* $response->appendBody($chunk);
|
||||
* }
|
||||
*
|
||||
* var_dump($response->getHeader(), $response->getCookies(), $response->getBody());
|
||||
* </code>
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6
|
||||
*/
|
||||
class HTTP_Request2_Response
|
||||
{
|
||||
/**
|
||||
* HTTP protocol version (e.g. 1.0, 1.1)
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
* @var integer
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
* @var string
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-6.1.1
|
||||
*/
|
||||
protected $reasonPhrase;
|
||||
|
||||
/**
|
||||
* Effective URL (may be different from original request URL in case of redirects)
|
||||
* @var string
|
||||
*/
|
||||
protected $effectiveUrl;
|
||||
|
||||
/**
|
||||
* Associative array of response headers
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* Cookies set in the response
|
||||
* @var array
|
||||
*/
|
||||
protected $cookies = array();
|
||||
|
||||
/**
|
||||
* Name of last header processed by parseHederLine()
|
||||
*
|
||||
* Used to handle the headers that span multiple lines
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastHeader = null;
|
||||
|
||||
/**
|
||||
* Response body
|
||||
* @var string
|
||||
*/
|
||||
protected $body = '';
|
||||
|
||||
/**
|
||||
* Whether the body is still encoded by Content-Encoding
|
||||
*
|
||||
* cURL provides the decoded body to the callback; if we are reading from
|
||||
* socket the body is still gzipped / deflated
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $bodyEncoded;
|
||||
|
||||
/**
|
||||
* Associative array of HTTP status code / reason phrase.
|
||||
*
|
||||
* @var array
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-10
|
||||
*/
|
||||
protected static $phrases = array(
|
||||
|
||||
// 1xx: Informational - Request received, continuing process
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
|
||||
// 2xx: Success - The action was successfully received, understood and
|
||||
// accepted
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
// 3xx: Redirection - Further action must be taken in order to complete
|
||||
// the request
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found', // 1.1
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
// 4xx: Client Error - The request contains bad syntax or cannot be
|
||||
// fulfilled
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
// 5xx: Server Error - The server failed to fulfill an apparently
|
||||
// valid request
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
509 => 'Bandwidth Limit Exceeded',
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the default reason phrase for the given code or all reason phrases
|
||||
*
|
||||
* @param int $code Response code
|
||||
*
|
||||
* @return string|array|null Default reason phrase for $code if $code is given
|
||||
* (null if no phrase is available), array of all
|
||||
* reason phrases if $code is null
|
||||
* @link http://pear.php.net/bugs/18716
|
||||
*/
|
||||
public static function getDefaultReasonPhrase($code = null)
|
||||
{
|
||||
if (null === $code) {
|
||||
return self::$phrases;
|
||||
} else {
|
||||
return isset(self::$phrases[$code]) ? self::$phrases[$code] : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, parses the response status line
|
||||
*
|
||||
* @param string $statusLine Response status line (e.g. "HTTP/1.1 200 OK")
|
||||
* @param bool $bodyEncoded Whether body is still encoded by Content-Encoding
|
||||
* @param string $effectiveUrl Effective URL of the response
|
||||
*
|
||||
* @throws HTTP_Request2_MessageException if status line is invalid according to spec
|
||||
*/
|
||||
public function __construct($statusLine, $bodyEncoded = true, $effectiveUrl = null)
|
||||
{
|
||||
if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Malformed response: {$statusLine}",
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
$this->version = $m[1];
|
||||
$this->code = intval($m[2]);
|
||||
$this->reasonPhrase = !empty($m[3]) ? trim($m[3]) : self::getDefaultReasonPhrase($this->code);
|
||||
$this->bodyEncoded = (bool)$bodyEncoded;
|
||||
$this->effectiveUrl = (string)$effectiveUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the line from HTTP response filling $headers array
|
||||
*
|
||||
* The method should be called after reading the line from socket or receiving
|
||||
* it into cURL callback. Passing an empty string here indicates the end of
|
||||
* response headers and triggers additional processing, so be sure to pass an
|
||||
* empty string in the end.
|
||||
*
|
||||
* @param string $headerLine Line from HTTP response
|
||||
*/
|
||||
public function parseHeaderLine($headerLine)
|
||||
{
|
||||
$headerLine = trim($headerLine, "\r\n");
|
||||
|
||||
if ('' == $headerLine) {
|
||||
// empty string signals the end of headers, process the received ones
|
||||
if (!empty($this->headers['set-cookie'])) {
|
||||
$cookies = is_array($this->headers['set-cookie'])?
|
||||
$this->headers['set-cookie']:
|
||||
array($this->headers['set-cookie']);
|
||||
foreach ($cookies as $cookieString) {
|
||||
$this->parseCookie($cookieString);
|
||||
}
|
||||
unset($this->headers['set-cookie']);
|
||||
}
|
||||
foreach (array_keys($this->headers) as $k) {
|
||||
if (is_array($this->headers[$k])) {
|
||||
$this->headers[$k] = implode(', ', $this->headers[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) {
|
||||
// string of the form header-name: header value
|
||||
$name = strtolower($m[1]);
|
||||
$value = trim($m[2]);
|
||||
if (empty($this->headers[$name])) {
|
||||
$this->headers[$name] = $value;
|
||||
} else {
|
||||
if (!is_array($this->headers[$name])) {
|
||||
$this->headers[$name] = array($this->headers[$name]);
|
||||
}
|
||||
$this->headers[$name][] = $value;
|
||||
}
|
||||
$this->lastHeader = $name;
|
||||
|
||||
} elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) {
|
||||
// continuation of a previous header
|
||||
if (!is_array($this->headers[$this->lastHeader])) {
|
||||
$this->headers[$this->lastHeader] .= ' ' . trim($m[1]);
|
||||
} else {
|
||||
$key = count($this->headers[$this->lastHeader]) - 1;
|
||||
$this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Set-Cookie header to fill $cookies array
|
||||
*
|
||||
* @param string $cookieString value of Set-Cookie header
|
||||
*
|
||||
* @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html
|
||||
*/
|
||||
protected function parseCookie($cookieString)
|
||||
{
|
||||
$cookie = array(
|
||||
'expires' => null,
|
||||
'domain' => null,
|
||||
'path' => null,
|
||||
'secure' => false
|
||||
);
|
||||
|
||||
if (!strpos($cookieString, ';')) {
|
||||
// Only a name=value pair
|
||||
$pos = strpos($cookieString, '=');
|
||||
$cookie['name'] = trim(substr($cookieString, 0, $pos));
|
||||
$cookie['value'] = trim(substr($cookieString, $pos + 1));
|
||||
|
||||
} else {
|
||||
// Some optional parameters are supplied
|
||||
$elements = explode(';', $cookieString);
|
||||
$pos = strpos($elements[0], '=');
|
||||
$cookie['name'] = trim(substr($elements[0], 0, $pos));
|
||||
$cookie['value'] = trim(substr($elements[0], $pos + 1));
|
||||
|
||||
for ($i = 1; $i < count($elements); $i++) {
|
||||
if (false === strpos($elements[$i], '=')) {
|
||||
$elName = trim($elements[$i]);
|
||||
$elValue = null;
|
||||
} else {
|
||||
list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
|
||||
}
|
||||
$elName = strtolower($elName);
|
||||
if ('secure' == $elName) {
|
||||
$cookie['secure'] = true;
|
||||
} elseif ('expires' == $elName) {
|
||||
$cookie['expires'] = str_replace('"', '', $elValue);
|
||||
} elseif ('path' == $elName || 'domain' == $elName) {
|
||||
$cookie[$elName] = urldecode($elValue);
|
||||
} else {
|
||||
$cookie[$elName] = $elValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->cookies[] = $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string to the response body
|
||||
*
|
||||
* @param string $bodyChunk part of response body
|
||||
*/
|
||||
public function appendBody($bodyChunk)
|
||||
{
|
||||
$this->body .= $bodyChunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective URL of the response
|
||||
*
|
||||
* This may be different from the request URL if redirects were followed.
|
||||
*
|
||||
* @return string
|
||||
* @link http://pear.php.net/bugs/bug.php?id=18412
|
||||
*/
|
||||
public function getEffectiveUrl()
|
||||
{
|
||||
return $this->effectiveUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status code
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason phrase
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase()
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether response is a redirect that can be automatically handled by HTTP_Request2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->code, array(300, 301, 302, 303, 307))
|
||||
&& isset($this->headers['location']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either the named header or all response headers
|
||||
*
|
||||
* @param string $headerName Name of header to return
|
||||
*
|
||||
* @return string|array Value of $headerName header (null if header is
|
||||
* not present), array of all response headers if
|
||||
* $headerName is null
|
||||
*/
|
||||
public function getHeader($headerName = null)
|
||||
{
|
||||
if (null === $headerName) {
|
||||
return $this->headers;
|
||||
} else {
|
||||
$headerName = strtolower($headerName);
|
||||
return isset($this->headers[$headerName])? $this->headers[$headerName]: null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cookies set in response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCookies()
|
||||
{
|
||||
return $this->cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body of the response
|
||||
*
|
||||
* @return string
|
||||
* @throws HTTP_Request2_Exception if body cannot be decoded
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
if (0 == strlen($this->body) || !$this->bodyEncoded
|
||||
|| !in_array(strtolower($this->getHeader('content-encoding')), array('gzip', 'deflate'))
|
||||
) {
|
||||
return $this->body;
|
||||
|
||||
} else {
|
||||
if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) {
|
||||
$oldEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('8bit');
|
||||
}
|
||||
|
||||
try {
|
||||
switch (strtolower($this->getHeader('content-encoding'))) {
|
||||
case 'gzip':
|
||||
$decoded = self::decodeGzip($this->body);
|
||||
break;
|
||||
case 'deflate':
|
||||
$decoded = self::decodeDeflate($this->body);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
if (!empty($oldEncoding)) {
|
||||
mb_internal_encoding($oldEncoding);
|
||||
}
|
||||
if (!empty($e)) {
|
||||
throw $e;
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTTP version of the response
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether data starts with GZIP format identification bytes from RFC 1952
|
||||
*
|
||||
* @param string $data gzip-encoded (presumably) data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasGzipIdentification($data)
|
||||
{
|
||||
return 0 === strcmp(substr($data, 0, 2), "\x1f\x8b");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to parse GZIP format header in the given string
|
||||
*
|
||||
* If the header conforms to RFC 1952, its length is returned. If any
|
||||
* sanity check fails, HTTP_Request2_MessageException is thrown.
|
||||
*
|
||||
* Note: This function might be usable outside of HTTP_Request2 so it might
|
||||
* be good idea to be moved to some common package. (Delian Krustev)
|
||||
*
|
||||
* @param string $data Either the complete response body or
|
||||
* the leading part of it
|
||||
* @param boolean $dataComplete Whether $data contains complete response body
|
||||
*
|
||||
* @return int gzip header length in bytes
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @link http://tools.ietf.org/html/rfc1952
|
||||
*/
|
||||
public static function parseGzipHeader($data, $dataComplete = false)
|
||||
{
|
||||
// if data is complete, trailing 8 bytes should be present for size and crc32
|
||||
$length = strlen($data) - ($dataComplete ? 8 : 0);
|
||||
|
||||
if ($length < 10 || !self::hasGzipIdentification($data)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'The data does not seem to contain a valid gzip header',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
$method = ord(substr($data, 2, 1));
|
||||
if (8 != $method) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: unknown compression method',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$flags = ord(substr($data, 3, 1));
|
||||
if ($flags & 224) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: reserved bits are set',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// header is 10 bytes minimum. may be longer, though.
|
||||
$headerLength = 10;
|
||||
// extra fields, need to skip 'em
|
||||
if ($flags & 4) {
|
||||
if ($length - $headerLength - 2 < 0) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$extraLength = unpack('v', substr($data, 10, 2));
|
||||
if ($length - $headerLength - 2 - $extraLength[1] < 0) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $extraLength[1] + 2;
|
||||
}
|
||||
// file name, need to skip that
|
||||
if ($flags & 8) {
|
||||
if ($length - $headerLength - 1 < 0) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$filenameLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $filenameLength
|
||||
|| $length - $headerLength - $filenameLength - 1 < 0
|
||||
) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $filenameLength + 1;
|
||||
}
|
||||
// comment, need to skip that also
|
||||
if ($flags & 16) {
|
||||
if ($length - $headerLength - 1 < 0) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$commentLength = strpos(substr($data, $headerLength), chr(0));
|
||||
if (false === $commentLength
|
||||
|| $length - $headerLength - $commentLength - 1 < 0
|
||||
) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += $commentLength + 1;
|
||||
}
|
||||
// have a CRC for header. let's check
|
||||
if ($flags & 2) {
|
||||
if ($length - $headerLength - 2 < 0) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Error parsing gzip header: data too short',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$crcReal = 0xffff & crc32(substr($data, 0, $headerLength));
|
||||
$crcStored = unpack('v', substr($data, $headerLength, 2));
|
||||
if ($crcReal != $crcStored[1]) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Header CRC check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
$headerLength += 2;
|
||||
}
|
||||
return $headerLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by gzip
|
||||
*
|
||||
* The real decoding work is done by gzinflate() built-in function, this
|
||||
* method only parses the header and checks data for compliance with
|
||||
* RFC 1952
|
||||
*
|
||||
* @param string $data gzip-encoded data
|
||||
*
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @link http://tools.ietf.org/html/rfc1952
|
||||
*/
|
||||
public static function decodeGzip($data)
|
||||
{
|
||||
// If it doesn't look like gzip-encoded data, don't bother
|
||||
if (!self::hasGzipIdentification($data)) {
|
||||
return $data;
|
||||
}
|
||||
if (!function_exists('gzinflate')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Unable to decode body: gzip extension not available',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
|
||||
// unpacked data CRC and size at the end of encoded data
|
||||
$tmp = unpack('V2', substr($data, -8));
|
||||
$dataCrc = $tmp[1];
|
||||
$dataSize = $tmp[2];
|
||||
|
||||
$headerLength = self::parseGzipHeader($data, true);
|
||||
|
||||
// don't pass $dataSize to gzinflate, see bugs #13135, #14370
|
||||
$unpacked = gzinflate(substr($data, $headerLength, -8));
|
||||
if (false === $unpacked) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'gzinflate() call failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
} elseif ($dataSize != strlen($unpacked)) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Data size check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
} elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Data CRC check failed',
|
||||
HTTP_Request2_Exception::DECODE_ERROR
|
||||
);
|
||||
}
|
||||
return $unpacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the message-body encoded by deflate
|
||||
*
|
||||
* @param string $data deflate-encoded data
|
||||
*
|
||||
* @return string decoded data
|
||||
* @throws HTTP_Request2_LogicException
|
||||
*/
|
||||
public static function decodeDeflate($data)
|
||||
{
|
||||
if (!function_exists('gzuncompress')) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
'Unable to decode body: gzip extension not available',
|
||||
HTTP_Request2_Exception::MISCONFIGURATION
|
||||
);
|
||||
}
|
||||
// RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950,
|
||||
// while many applications send raw deflate stream from RFC 1951.
|
||||
// We should check for presence of zlib header and use gzuncompress() or
|
||||
// gzinflate() as needed. See bug #15305
|
||||
$header = unpack('n', substr($data, 0, 2));
|
||||
return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* SOCKS5 proxy connection class
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Socket wrapper class used by Socket Adapter */
|
||||
require_once 'HTTP/Request2/SocketWrapper.php';
|
||||
|
||||
/**
|
||||
* SOCKS5 proxy connection class (used by Socket Adapter)
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/bugs/bug.php?id=19332
|
||||
* @link http://tools.ietf.org/html/rfc1928
|
||||
*/
|
||||
class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper
|
||||
{
|
||||
/**
|
||||
* Constructor, tries to connect and authenticate to a SOCKS5 proxy
|
||||
*
|
||||
* @param string $address Proxy address, e.g. 'tcp://localhost:1080'
|
||||
* @param int $timeout Connection timeout (seconds)
|
||||
* @param array $contextOptions Stream context options
|
||||
* @param string $username Proxy user name
|
||||
* @param string $password Proxy password
|
||||
*
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function __construct(
|
||||
$address, $timeout = 10, array $contextOptions = array(),
|
||||
$username = null, $password = null
|
||||
) {
|
||||
parent::__construct($address, $timeout, $contextOptions);
|
||||
|
||||
if (strlen($username)) {
|
||||
$request = pack('C4', 5, 2, 0, 2);
|
||||
} else {
|
||||
$request = pack('C3', 5, 1, 0);
|
||||
}
|
||||
$this->write($request);
|
||||
$response = unpack('Cversion/Cmethod', $this->read(3));
|
||||
if (5 != $response['version']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Invalid version received from SOCKS5 proxy: ' . $response['version'],
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
}
|
||||
switch ($response['method']) {
|
||||
case 2:
|
||||
$this->performAuthentication($username, $password);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Connection rejected by proxy due to unsupported auth method"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs username/password authentication for SOCKS5
|
||||
*
|
||||
* @param string $username Proxy user name
|
||||
* @param string $password Proxy password
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
* @link http://tools.ietf.org/html/rfc1929
|
||||
*/
|
||||
protected function performAuthentication($username, $password)
|
||||
{
|
||||
$request = pack('C2', 1, strlen($username)) . $username
|
||||
. pack('C', strlen($password)) . $password;
|
||||
|
||||
$this->write($request);
|
||||
$response = unpack('Cvn/Cstatus', $this->read(3));
|
||||
if (1 != $response['vn'] || 0 != $response['status']) {
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
'Connection rejected by proxy due to invalid username and/or password'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a remote host via proxy
|
||||
*
|
||||
* @param string $remoteHost Remote host
|
||||
* @param int $remotePort Remote port
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function connect($remoteHost, $remotePort)
|
||||
{
|
||||
$request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost))
|
||||
. $remoteHost . pack('n', $remotePort);
|
||||
|
||||
$this->write($request);
|
||||
$response = unpack('Cversion/Creply/Creserved', $this->read(1024));
|
||||
if (5 != $response['version'] || 0 != $response['reserved']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
'Invalid response received from SOCKS5 proxy',
|
||||
HTTP_Request2_Exception::MALFORMED_RESPONSE
|
||||
);
|
||||
} elseif (0 != $response['reply']) {
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy",
|
||||
0, $response['reply']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
/**
|
||||
* Socket wrapper class used by Socket Adapter
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to BSD 3-Clause License that is bundled
|
||||
* with this package in the file LICENSE and available at the URL
|
||||
* https://raw.github.com/pear/HTTP_Request2/trunk/docs/LICENSE
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @copyright 2008-2016 Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
*/
|
||||
|
||||
/** Exception classes for HTTP_Request2 package */
|
||||
require_once 'HTTP/Request2/Exception.php';
|
||||
|
||||
/**
|
||||
* Socket wrapper class used by Socket Adapter
|
||||
*
|
||||
* Needed to properly handle connection errors, global timeout support and
|
||||
* similar things. Loosely based on Net_Socket used by older HTTP_Request.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request2
|
||||
* @author Alexey Borzov <avb@php.net>
|
||||
* @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
|
||||
* @version Release: 2.3.0
|
||||
* @link http://pear.php.net/package/HTTP_Request2
|
||||
* @link http://pear.php.net/bugs/bug.php?id=19332
|
||||
* @link http://tools.ietf.org/html/rfc1928
|
||||
*/
|
||||
class HTTP_Request2_SocketWrapper
|
||||
{
|
||||
/**
|
||||
* PHP warning messages raised during stream_socket_client() call
|
||||
* @var array
|
||||
*/
|
||||
protected $connectionWarnings = array();
|
||||
|
||||
/**
|
||||
* Connected socket
|
||||
* @var resource
|
||||
*/
|
||||
protected $socket;
|
||||
|
||||
/**
|
||||
* Sum of start time and global timeout, exception will be thrown if request continues past this time
|
||||
* @var integer
|
||||
*/
|
||||
protected $deadline;
|
||||
|
||||
/**
|
||||
* Global timeout value, mostly for exception messages
|
||||
* @var integer
|
||||
*/
|
||||
protected $timeout;
|
||||
|
||||
/**
|
||||
* Class constructor, tries to establish connection
|
||||
*
|
||||
* @param string $address Address for stream_socket_client() call,
|
||||
* e.g. 'tcp://localhost:80'
|
||||
* @param int $timeout Connection timeout (seconds)
|
||||
* @param array $contextOptions Context options
|
||||
*
|
||||
* @throws HTTP_Request2_LogicException
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
*/
|
||||
public function __construct($address, $timeout, array $contextOptions = array())
|
||||
{
|
||||
if (!empty($contextOptions)
|
||||
&& !isset($contextOptions['socket']) && !isset($contextOptions['ssl'])
|
||||
) {
|
||||
// Backwards compatibility with 2.1.0 and 2.1.1 releases
|
||||
$contextOptions = array('ssl' => $contextOptions);
|
||||
}
|
||||
if (isset($contextOptions['ssl'])) {
|
||||
$contextOptions['ssl'] += array(
|
||||
// Using "Intermediate compatibility" cipher bundle from
|
||||
// https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||
'ciphers' => 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:'
|
||||
. 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:'
|
||||
. 'DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:'
|
||||
. 'ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:'
|
||||
. 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:'
|
||||
. 'ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:'
|
||||
. 'ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:'
|
||||
. 'DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:'
|
||||
. 'DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:'
|
||||
. 'ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:'
|
||||
. 'AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:'
|
||||
. 'AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:'
|
||||
. '!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'
|
||||
);
|
||||
if (version_compare(phpversion(), '5.4.13', '>=')) {
|
||||
$contextOptions['ssl']['disable_compression'] = true;
|
||||
if (version_compare(phpversion(), '5.6', '>=')) {
|
||||
$contextOptions['ssl']['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
|
||||
| STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
$context = stream_context_create();
|
||||
foreach ($contextOptions as $wrapper => $options) {
|
||||
foreach ($options as $name => $value) {
|
||||
if (!stream_context_set_option($context, $wrapper, $name, $value)) {
|
||||
throw new HTTP_Request2_LogicException(
|
||||
"Error setting '{$wrapper}' wrapper context option '{$name}'"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
set_error_handler(array($this, 'connectionWarningsHandler'));
|
||||
$this->socket = stream_socket_client(
|
||||
$address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context
|
||||
);
|
||||
restore_error_handler();
|
||||
// if we fail to bind to a specified local address (see request #19515),
|
||||
// connection still succeeds, albeit with a warning. Throw an Exception
|
||||
// with the warning text in this case as that connection is unlikely
|
||||
// to be what user wants and as Curl throws an error in similar case.
|
||||
if ($this->connectionWarnings) {
|
||||
if ($this->socket) {
|
||||
fclose($this->socket);
|
||||
}
|
||||
$error = $errstr ? $errstr : implode("\n", $this->connectionWarnings);
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
"Unable to connect to {$address}. Error: {$error}", 0, $errno
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, disconnects socket
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
fclose($this->socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around fread(), handles global request timeout
|
||||
*
|
||||
* @param int $length Reads up to this number of bytes
|
||||
*
|
||||
* @return string Data read from socket
|
||||
* @throws HTTP_Request2_MessageException In case of timeout
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
if ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
$data = fread($this->socket, $length);
|
||||
$this->checkTimeout();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads until either the end of the socket or a newline, whichever comes first
|
||||
*
|
||||
* Strips the trailing newline from the returned data, handles global
|
||||
* request timeout. Method idea borrowed from Net_Socket PEAR package.
|
||||
*
|
||||
* @param int $bufferSize buffer size to use for reading
|
||||
* @param int $localTimeout timeout value to use just for this call
|
||||
* (used when waiting for "100 Continue" response)
|
||||
*
|
||||
* @return string Available data up to the newline (not including newline)
|
||||
* @throws HTTP_Request2_MessageException In case of timeout
|
||||
*/
|
||||
public function readLine($bufferSize, $localTimeout = null)
|
||||
{
|
||||
$line = '';
|
||||
while (!feof($this->socket)) {
|
||||
if (null !== $localTimeout) {
|
||||
stream_set_timeout($this->socket, $localTimeout);
|
||||
} elseif ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
|
||||
$line .= @fgets($this->socket, $bufferSize);
|
||||
|
||||
if (null === $localTimeout) {
|
||||
$this->checkTimeout();
|
||||
|
||||
} else {
|
||||
$info = stream_get_meta_data($this->socket);
|
||||
// reset socket timeout if we don't have request timeout specified,
|
||||
// prevents further calls failing with a bogus Exception
|
||||
if (!$this->deadline) {
|
||||
$default = (int)@ini_get('default_socket_timeout');
|
||||
stream_set_timeout($this->socket, $default > 0 ? $default : PHP_INT_MAX);
|
||||
}
|
||||
if ($info['timed_out']) {
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"readLine() call timed out", HTTP_Request2_Exception::TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
if (substr($line, -1) == "\n") {
|
||||
return rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around fwrite(), handles global request timeout
|
||||
*
|
||||
* @param string $data String to be written
|
||||
*
|
||||
* @return int
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
if ($this->deadline) {
|
||||
stream_set_timeout($this->socket, max($this->deadline - time(), 1));
|
||||
}
|
||||
$written = fwrite($this->socket, $data);
|
||||
$this->checkTimeout();
|
||||
// http://www.php.net/manual/en/function.fwrite.php#96951
|
||||
if ($written < strlen($data)) {
|
||||
throw new HTTP_Request2_MessageException('Error writing request');
|
||||
}
|
||||
return $written;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for end-of-file on a socket
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function eof()
|
||||
{
|
||||
return feof($this->socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets request deadline
|
||||
*
|
||||
* @param int $deadline Exception will be thrown if request continues
|
||||
* past this time
|
||||
* @param int $timeout Original request timeout value, to use in
|
||||
* Exception message
|
||||
*/
|
||||
public function setDeadline($deadline, $timeout)
|
||||
{
|
||||
$this->deadline = $deadline;
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on encryption on a socket
|
||||
*
|
||||
* @throws HTTP_Request2_ConnectionException
|
||||
*/
|
||||
public function enableCrypto()
|
||||
{
|
||||
if (version_compare(phpversion(), '5.6', '<')) {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
|
||||
} else {
|
||||
$cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
|
||||
| STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
|
||||
}
|
||||
|
||||
if (!stream_socket_enable_crypto($this->socket, true, $cryptoMethod)) {
|
||||
throw new HTTP_Request2_ConnectionException(
|
||||
'Failed to enable secure connection when connecting through proxy'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an Exception if stream timed out
|
||||
*
|
||||
* @throws HTTP_Request2_MessageException
|
||||
*/
|
||||
protected function checkTimeout()
|
||||
{
|
||||
$info = stream_get_meta_data($this->socket);
|
||||
if ($info['timed_out'] || $this->deadline && time() > $this->deadline) {
|
||||
$reason = $this->deadline
|
||||
? "after {$this->timeout} second(s)"
|
||||
: 'due to default_socket_timeout php.ini setting';
|
||||
throw new HTTP_Request2_MessageException(
|
||||
"Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error handler to use during stream_socket_client() call
|
||||
*
|
||||
* One stream_socket_client() call may produce *multiple* PHP warnings
|
||||
* (especially OpenSSL-related), we keep them in an array to later use for
|
||||
* the message of HTTP_Request2_ConnectionException
|
||||
*
|
||||
* @param int $errno error level
|
||||
* @param string $errstr error message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function connectionWarningsHandler($errno, $errstr)
|
||||
{
|
||||
if ($errno & E_WARNING) {
|
||||
array_unshift($this->connectionWarnings, $errstr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
+229
-52
@@ -1,22 +1,6 @@
|
||||
<?php
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PEAR::Net_DNSBL |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2004 Sebastian Nohn <sebastian@nohn.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available through the world-wide-web at the following url: |
|
||||
// | http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Sebastian Nohn <sebastian@nohn.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: DNSBL.php,v 1.4 2004/12/02 14:23:51 nohn Exp $
|
||||
|
||||
/**
|
||||
* PEAR::Net_DNSBL
|
||||
@@ -24,17 +8,49 @@
|
||||
* This class acts as interface to generic Realtime Blocking Lists
|
||||
* (RBL)
|
||||
*
|
||||
* Net_RBL looks up an supplied host if it's listed in 1-n supplied
|
||||
* PHP versions 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* Net_DNSBL looks up an supplied host if it's listed in 1-n supplied
|
||||
* Blacklists
|
||||
*
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @package Net_DNSBL
|
||||
* @license http://www.php.net/license/3_0.txt
|
||||
* @version 0.5.3
|
||||
* @category Net
|
||||
* @package Net_DNSBL
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @author Ammar Ibrahim <fixxme@fixme.com>
|
||||
* @copyright 2004-2012 Sebastian Nohn <sebastian@nohn.net>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: DNSBL.php 325344 2012-04-20 04:31:30Z nohn $
|
||||
* @link http://pear.php.net/package/Net_DNSBL
|
||||
* @see Net_DNS
|
||||
* @since File available since Release 1.0.0
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/CheckIP.php';
|
||||
|
||||
class Net_DNSBL {
|
||||
require_once 'Net/DNS.php';
|
||||
|
||||
/**
|
||||
* PEAR::Net_DNSBL
|
||||
*
|
||||
* This class acts as interface to DNSBLs
|
||||
*
|
||||
* Net_DNSBL looks up an supplied IP if it's listed in a
|
||||
* DNS Blacklist.
|
||||
*
|
||||
* @category Net
|
||||
* @package Net_DNSBL
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version Release: 1.3.7
|
||||
* @link http://pear.php.net/package/net_dnsbl Package Home
|
||||
*/
|
||||
|
||||
class Net_DNSBL
|
||||
{
|
||||
|
||||
/**
|
||||
* Array of blacklists.
|
||||
@@ -44,17 +60,26 @@ class Net_DNSBL {
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
var $blacklists = array('sbl-xbl.spamhaus.net',
|
||||
'bl.spamcop.net');
|
||||
protected $blacklists = array('sbl-xbl.spamhaus.org',
|
||||
'bl.spamcop.net');
|
||||
|
||||
/**
|
||||
* Array of Results
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $results = array();
|
||||
|
||||
/**
|
||||
* Set the blacklist to a desired blacklist.
|
||||
*
|
||||
* @param array Array of blacklists to use. May contain only one element.
|
||||
* @param array $blacklists Array of blacklists to use.
|
||||
*
|
||||
* @access public
|
||||
* @return bool true if the operation was successful
|
||||
*/
|
||||
function setBlacklists($blacklists)
|
||||
public function setBlacklists($blacklists)
|
||||
{
|
||||
if (is_array($blacklists)) {
|
||||
$this->blacklists = $blacklists;
|
||||
@@ -70,32 +95,176 @@ class Net_DNSBL {
|
||||
* @access public
|
||||
* @return array Currently set blacklists.
|
||||
*/
|
||||
function getBlacklists()
|
||||
public function getBlacklists()
|
||||
{
|
||||
return $this->blacklists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Blacklist and Reply from the Blacklist, a host is listed in.
|
||||
*
|
||||
* @param string $host Host to check
|
||||
*
|
||||
* @access public
|
||||
* @return array result. $result['dnsbl'] contains DNSBL,
|
||||
* $result['record'] contains returned DNS record.
|
||||
*/
|
||||
public function getDetails($host)
|
||||
{
|
||||
if (isset($this->results[$host])) {
|
||||
return $this->results[$host];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} // function
|
||||
|
||||
/**
|
||||
* Returns Blacklist, host is listed in.
|
||||
*
|
||||
* @param string $host Host to check
|
||||
*
|
||||
* @access public
|
||||
* @return bl, a host is listed in or false
|
||||
*/
|
||||
public function getListingBl($host)
|
||||
{
|
||||
if (isset($this->results[$host]['dnsbl'])) {
|
||||
return $this->results[$host]['dnsbl'];
|
||||
}
|
||||
|
||||
if (isset($this->results[$host]) && is_array($this->results[$host])) {
|
||||
$result = array_keys($this->results[$host]);
|
||||
if ($result == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return 'multiple ('.implode(', ', $result).')';
|
||||
}
|
||||
return false;
|
||||
} // function
|
||||
|
||||
/**
|
||||
* Returns Blacklists, host is listed in. isListed() must have
|
||||
* been called with checkall = true
|
||||
*
|
||||
* @param string $host Host to check
|
||||
*
|
||||
* @access public
|
||||
* @return array blacklists, a host is listed in or false
|
||||
*/
|
||||
public function getListingBls($host)
|
||||
{
|
||||
if (isset($this->results[$host]) && is_array($this->results[$host])) {
|
||||
$result = array_keys($this->results[$host]);
|
||||
if ($result == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} // function
|
||||
|
||||
/**
|
||||
* Returns result, when a host is listed.
|
||||
*
|
||||
* @param string $host Host to check
|
||||
*
|
||||
* @access public
|
||||
* @return bl, a host is listed in or false
|
||||
*/
|
||||
public function getListingRecord($host)
|
||||
{
|
||||
if (isset($this->results[$host]['record'])) {
|
||||
return $this->results[$host]['record'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} // function
|
||||
|
||||
/**
|
||||
* Returns TXT-Records, when a host is listed.
|
||||
*
|
||||
* @param string $host Host to check
|
||||
*
|
||||
* @access public
|
||||
* @return array TXT-Records for this host
|
||||
*/
|
||||
public function getTxt($host)
|
||||
{
|
||||
if (isset($this->results[$host]['txt'])) {
|
||||
return $this->results[$host]['txt'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} // function
|
||||
|
||||
/**
|
||||
* Checks if the supplied Host is listed in one or more of the
|
||||
* RBLs.
|
||||
*
|
||||
* @param string Host to check for being listed.
|
||||
* @param string $host Host to check for being listed.
|
||||
* @param boolean $checkall Iterate through all blacklists and
|
||||
* return all A records or stop after
|
||||
* the first hit?
|
||||
*
|
||||
* @access public
|
||||
* @return boolean true if the checked host is listed in a blacklist.
|
||||
*/
|
||||
function isListed($host)
|
||||
public function isListed($host, $checkall = false)
|
||||
{
|
||||
|
||||
$isListed = false;
|
||||
|
||||
$resolver = new Net_DNS_Resolver;
|
||||
|
||||
if (!is_string($host)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->blacklists as $blacklist) {
|
||||
$result = gethostbyname($this->getHostForLookup($host, $blacklist));
|
||||
if ($result != $this->getHostForLookup($host, $blacklist)) {
|
||||
$response = $resolver->query($this->getHostForLookup($host, $blacklist));
|
||||
if ($response) {
|
||||
$isListed = true;
|
||||
|
||||
//if the Host was listed we don't need to check other RBLs,
|
||||
break;
|
||||
|
||||
if ($checkall) {
|
||||
$this->results[$host][$blacklist] = array();
|
||||
foreach ($response->answer as $answer) {
|
||||
$this->results[$host][$blacklist]['record'][]
|
||||
= $answer->address;
|
||||
}
|
||||
$response_txt
|
||||
= $resolver->query(
|
||||
$this->getHostForLookup(
|
||||
$host,
|
||||
$blacklist
|
||||
),
|
||||
'TXT'
|
||||
);
|
||||
if (isset($response_txt->answer)) {
|
||||
foreach ($response_txt->answer as $txt) {
|
||||
$this->results[$host][$blacklist]['txt'][]
|
||||
= $txt->text[0];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->results[$host]['dnsbl'] = $blacklist;
|
||||
$this->results[$host]['record'] = $response->answer[0]->address;
|
||||
$response_txt
|
||||
= $resolver->query(
|
||||
$this->getHostForLookup(
|
||||
$host,
|
||||
$blacklist
|
||||
),
|
||||
'TXT'
|
||||
);
|
||||
if ((isset($response_txt)) && ($response_txt != false)) {
|
||||
foreach ($response_txt->answer as $txt) {
|
||||
$this->results[$host]['txt'][] = $txt->text[0];
|
||||
}
|
||||
}
|
||||
// if the Host was listed we don't need to check other RBLs,
|
||||
break;
|
||||
}
|
||||
} // if
|
||||
} // foreach
|
||||
|
||||
@@ -106,18 +275,25 @@ class Net_DNSBL {
|
||||
* Get host to lookup. Lookup a host if neccessary and get the
|
||||
* complete FQDN to lookup.
|
||||
*
|
||||
* @param string Host OR IP to use for building the lookup.
|
||||
* @param string Blacklist to use for building the lookup.
|
||||
* @param string $host Host OR IP to use for building the lookup.
|
||||
* @param string $blacklist Blacklist to use for building the lookup.
|
||||
*
|
||||
* @access protected
|
||||
* @return string Ready to use host to lookup
|
||||
*/
|
||||
function getHostForLookup($host, $blacklist)
|
||||
protected function getHostForLookup($host, $blacklist)
|
||||
{
|
||||
// Currently only works for v4 addresses.
|
||||
if (!Net_CheckIP::check_ip($host)) {
|
||||
$ip = gethostbyname($host);
|
||||
if (filter_var($host, FILTER_VALIDATE_IP)) {
|
||||
$ip = $host;
|
||||
} else {
|
||||
$ip = $host;
|
||||
$resolver = new Net_DNS_Resolver;
|
||||
$response = $resolver->query($host);
|
||||
$ip = isset($response->answer[0]->address) ?
|
||||
$response->answer[0]->address : null;
|
||||
}
|
||||
if (!$ip || !filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->buildLookUpHost($ip, $blacklist);
|
||||
@@ -126,12 +302,13 @@ class Net_DNSBL {
|
||||
/**
|
||||
* Build the host to lookup from an IP.
|
||||
*
|
||||
* @param string IP to use for building the lookup.
|
||||
* @param string Blacklist to use for building the lookup.
|
||||
* @param string $ip IP to use for building the lookup.
|
||||
* @param string $blacklist Blacklist to use for building the lookup.
|
||||
*
|
||||
* @access protected
|
||||
* @return string Ready to use host to lookup
|
||||
*/
|
||||
function buildLookUpHost($ip, $blacklist)
|
||||
protected function buildLookUpHost($ip, $blacklist)
|
||||
{
|
||||
return $this->reverseIp($ip).'.'.$blacklist;
|
||||
} // function
|
||||
@@ -140,14 +317,14 @@ class Net_DNSBL {
|
||||
* Reverse the order of an IP. 127.0.0.1 -> 1.0.0.127. Currently
|
||||
* only works for v4-adresses
|
||||
*
|
||||
* @param string IP to reverse.
|
||||
* @param string $ip IP address to reverse.
|
||||
*
|
||||
* @access protected
|
||||
* @return string Reversed IP
|
||||
*/
|
||||
function reverseIp($ip)
|
||||
protected function reverseIp($ip)
|
||||
{
|
||||
return implode('.', array_reverse(explode('.', $ip)));
|
||||
} // function
|
||||
|
||||
} // class
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -1,22 +1,39 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PEAR::Net_DNSBL_SURBL |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2004 Sebastian Nohn <sebastian@nohn.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available through the world-wide-web at the following url: |
|
||||
// | http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Sebastian Nohn <sebastian@nohn.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: SURBL.php,v 1.4 2004/12/02 14:23:51 nohn Exp $
|
||||
|
||||
/**
|
||||
* PEAR::Net_DNSBL
|
||||
*
|
||||
* This class acts as interface to generic Realtime Blocking Lists
|
||||
* (RBL)
|
||||
*
|
||||
* PHP versions 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
*
|
||||
* Net_DNSBL looks up an supplied host if it's listed in 1-n supplied
|
||||
* Blacklists
|
||||
*
|
||||
* @category Net
|
||||
* @package Net_DNSBL
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @author Ammar Ibrahim <fixxme@fixme.com>
|
||||
* @copyright 2004-2012 Sebastian Nohn <sebastian@nohn.net>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version CVS: $Id: SURBL.php 325344 2012-04-20 04:31:30Z nohn $
|
||||
* @link http://pear.php.net/package/Net_DNSBL
|
||||
* @see Net_DNS2
|
||||
* @since File available since Release 1.0.0
|
||||
*/
|
||||
|
||||
require_once 'Cache/Lite.php';
|
||||
require_once 'HTTP/Request2.php';
|
||||
require_once 'Net/DNSBL.php';
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* PEAR::Net_DNSBL_SURBL
|
||||
@@ -26,17 +43,16 @@
|
||||
* Services_SURBL looks up an supplied URI if it's listed in a
|
||||
* Spam URI Realtime Blocklists.
|
||||
*
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @package Net_DNSBL
|
||||
* @license http://www.php.net/license/3_0.txt
|
||||
* @version 0.5.4
|
||||
* @category Net
|
||||
* @package Net_DNSBL
|
||||
* @author Sebastian Nohn <sebastian@nohn.net>
|
||||
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
||||
* @version Release: 1.3.7
|
||||
* @link http://pear.php.net/package/net_dnsbl Package Home
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/../../Cache/Lite.php';
|
||||
require_once dirname(__FILE__) . '/../../HTTP/Request.php';
|
||||
require_once dirname(__FILE__) . '/../CheckIP.php';
|
||||
require_once dirname(__FILE__) . '/../DNSBL.php';
|
||||
|
||||
class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
class Net_DNSBL_SURBL extends Net_DNSBL
|
||||
{
|
||||
|
||||
/**
|
||||
* Array of blacklists.
|
||||
@@ -46,7 +62,7 @@ class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
* @var string[]
|
||||
* @access protected
|
||||
*/
|
||||
var $blacklists = array('multi.surbl.org');
|
||||
protected $blacklists = array('multi.surbl.org');
|
||||
|
||||
/**
|
||||
* File containing whitelisted hosts.
|
||||
@@ -59,41 +75,33 @@ class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
* @see $twoLevelCcTld
|
||||
* @access protected
|
||||
*/
|
||||
var $doubleCcTldFile = 'http://spamcheck.freeapp.net/two-level-tlds';
|
||||
|
||||
/**
|
||||
* Array of whitelisted hosts.
|
||||
*
|
||||
* @var array
|
||||
* @see $twoLevelCcTldFile
|
||||
* @access private
|
||||
*/
|
||||
var $twoLevelCcTld = array();
|
||||
protected $doubleCcTldFile = 'http://george.surbl.org/two-level-tlds';
|
||||
|
||||
/**
|
||||
* Check if the last two parts of the FQDN are whitelisted.
|
||||
*
|
||||
* @param string Host to check if it is whitelisted
|
||||
* @param string $fqdn Host to check if it is whitelisted.
|
||||
*
|
||||
* @access protected
|
||||
* @return boolean True if the host is whitelisted
|
||||
*/
|
||||
function isDoubleCcTld($fqdn)
|
||||
protected function isDoubleCcTld($fqdn)
|
||||
{
|
||||
// 30 Days should be way enough
|
||||
$options = array(
|
||||
'lifeTime' => '2592000',
|
||||
'automaticSerialization' => true
|
||||
);
|
||||
$id = md5($this->doubleCcTldFile);
|
||||
$id = md5($this->doubleCcTldFile);
|
||||
|
||||
$cache = new Cache_Lite($options);
|
||||
if ($data = $cache->get($id)) {
|
||||
// Cache hit
|
||||
} else {
|
||||
// Cache miss
|
||||
$http = new HTTP_Request($this->doubleCcTldFile);
|
||||
if (!PEAR::isError($http->sendRequest())) {
|
||||
$data = $http->getResponseBody();
|
||||
$http = new HTTP_Request2($this->doubleCcTldFile);
|
||||
if (!PEAR::isError($http->send())) {
|
||||
$data = $http->getBody();
|
||||
}
|
||||
$data = explode("\n", $data);
|
||||
$data = array_flip($data);
|
||||
@@ -119,18 +127,25 @@ class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
* (3b2) IS_NOT_2LEVEL: we want the last two names
|
||||
* (4) return the FQDN to query.
|
||||
*
|
||||
* @param string URL to check.
|
||||
* @param string $uri URL to check.
|
||||
* @param string $blacklist Blacklist to check against.
|
||||
*
|
||||
* @access protected
|
||||
* @return string Host to lookup
|
||||
*/
|
||||
function getHostForLookup($uri, $blacklist)
|
||||
protected function getHostForLookup($uri, $blacklist)
|
||||
{
|
||||
$host = '';
|
||||
// (1) Extract the hostname from the given URI
|
||||
$host = '';
|
||||
$parsed_uri = parse_url($uri);
|
||||
$host = $parsed_uri['host'];
|
||||
|
||||
if (empty($parsed_uri['host'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$host = urldecode($parsed_uri['host']);
|
||||
// (2) Check if the "hostname" is an ip
|
||||
if (Net_CheckIP::check_ip($host)) {
|
||||
if (filter_var($host, FILTER_VALIDATE_IP)) {
|
||||
// (3a) IS_IP Reverse the IP (1.2.3.4 -> 4.3.2.1)
|
||||
$host = $this->reverseIp($host);
|
||||
} else {
|
||||
@@ -139,13 +154,13 @@ class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
array_shift($host_elements);
|
||||
} // while
|
||||
$host_3_elements = implode('.', $host_elements);
|
||||
|
||||
|
||||
$host_elements = explode('.', $host);
|
||||
while (count($host_elements) > 2) {
|
||||
array_shift($host_elements);
|
||||
} // while
|
||||
$host_2_elements = implode('.', $host_elements);
|
||||
|
||||
|
||||
// (3b) IS_FQDN Check if is in "CC-2-level-TLD"
|
||||
if ($this->isDoubleCcTld($host_2_elements)) {
|
||||
// (3b1) IS_IN_2LEVEL: we want the last three names
|
||||
@@ -156,9 +171,9 @@ class Net_DNSBL_SURBL extends Net_DNSBL {
|
||||
} // if
|
||||
} // if
|
||||
// (4) return the FQDN to query
|
||||
$host .= '.'.$blacklist;
|
||||
$host .= '.'.$blacklist;
|
||||
return $host;
|
||||
} // function
|
||||
|
||||
|
||||
} // class
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -98,16 +98,6 @@ class Net_URL
|
||||
*/
|
||||
var $useBrackets;
|
||||
|
||||
/**
|
||||
* PHP4 Constructor
|
||||
*
|
||||
* @see __construct()
|
||||
*/
|
||||
function Net_URL($url = null, $useBrackets = true)
|
||||
{
|
||||
$this->__construct($url, $useBrackets);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP5 Constructor
|
||||
*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+23
-19
@@ -51,11 +51,6 @@ class ONYX_RSS
|
||||
* private $type;
|
||||
*/
|
||||
|
||||
function ONYX_RSS($charset = 'UTF-8')
|
||||
{
|
||||
$this->__construct($charset);
|
||||
}
|
||||
|
||||
// Forward compatibility with PHP v.5
|
||||
// http://www.phpvolcano.com/eide/php5.php?page=start
|
||||
function __construct($charset = 'UTF-8')
|
||||
@@ -127,20 +122,24 @@ class ONYX_RSS
|
||||
($file && file_exists($file) && $time <= $this->rss['cache_age'] && $mod >= (time() - ($this->rss['cache_age'] * 60))))
|
||||
{
|
||||
clearstatcache();
|
||||
|
||||
require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
|
||||
|
||||
require_once S9Y_PEAR_PATH . 'HTTP/Request2.php';
|
||||
serendipity_request_start();
|
||||
$req = new HTTP_Request($uri, array('allowRedirects' => true, 'maxRedirects' => 5));
|
||||
$res = $req->sendRequest();
|
||||
|
||||
if (PEAR::isError($res) || $req->getResponseCode() != '200')
|
||||
{
|
||||
$req = new HTTP_Request2($uri, HTTP_Request2::METHOD_GET, array('follow_redirects' => true, 'max_redirects' => 5));
|
||||
try {
|
||||
$res = $req->send();
|
||||
|
||||
if ($res->getStatus() != '200') {
|
||||
throw new HTTP_Request2_Exception('unable to fetch feed: status code != 200');
|
||||
}
|
||||
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
serendipity_request_end();
|
||||
$this->raiseError((__LINE__-2), ONYX_ERR_INVALID_URI . ' (#' . $req->getResponseCode() . ')');
|
||||
$this->raiseError((__LINE__-2), ONYX_ERR_INVALID_URI . ' (#' . $res->getStatus() . ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
$fContent = $req->getResponseBody();
|
||||
$fContent = $res->getBody();
|
||||
serendipity_request_end();
|
||||
if (@preg_match('@<?xml[^>]*encoding="([^"]+)"@i', $fContent, $xml_encoding)) {
|
||||
$this->rss['encoding'] = strtolower($xml_encoding[1]);
|
||||
@@ -171,7 +170,7 @@ class ONYX_RSS
|
||||
clearstatcache();
|
||||
if (!($fp = @fopen($file, 'r')))
|
||||
{
|
||||
$this->raiseError((__LINE__-2), 'Could not read contents of cache file (<em>'.$cache_file.'</em>).');
|
||||
$this->raiseError((__LINE__-2), 'Could not read contents of cache file (<em>'.$file.'</em>).');
|
||||
return false;
|
||||
}
|
||||
$this->data = unserialize(fread($fp, filesize($file)));
|
||||
@@ -347,16 +346,21 @@ class ONYX_RSS
|
||||
{
|
||||
if (function_exists('version_compare') && version_compare(phpversion(), '4.3.0') >= 0)
|
||||
{
|
||||
require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
|
||||
require_once S9Y_PEAR_PATH . 'HTTP/Request2.php';
|
||||
serendipity_request_start();
|
||||
$req = new HTTP_Request($uri);
|
||||
$req = new HTTP_Request2($uri);
|
||||
|
||||
if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
|
||||
try {
|
||||
$response = $req->send();
|
||||
if ($response->getStatus() != '200') {
|
||||
throw new HTTP_Request2_Exception('could not fetch url: status code != 200');
|
||||
}
|
||||
} catch (HTTP_Request2_Exception $e) {
|
||||
serendipity_request_end();
|
||||
return false;
|
||||
}
|
||||
|
||||
$fHeader = $req->getResponseHeader();
|
||||
$fHeader = $response->getHeader();
|
||||
if (isset($fHeader['last-modified'])) {
|
||||
$modtime = $fHeader['last-modified'];
|
||||
}
|
||||
|
||||
+292
-242
@@ -1,32 +1,26 @@
|
||||
<?php
|
||||
//
|
||||
// +--------------------------------------------------------------------+
|
||||
// | PEAR, the PHP Extension and Application Repository |
|
||||
// +--------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2004 The PHP Group |
|
||||
// +--------------------------------------------------------------------+
|
||||
// | This source file is subject to version 3.0 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available through the world-wide-web at the following url: |
|
||||
// | http://www.php.net/license/3_0.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +--------------------------------------------------------------------+
|
||||
// | Authors: Sterling Hughes <sterling@php.net> |
|
||||
// | Stig Bakken <ssb@php.net> |
|
||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
||||
// +--------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: PEAR.php,v 1.83 2005/03/28 16:38:58 cellog Exp $
|
||||
//
|
||||
|
||||
// Serendipity-Patch
|
||||
if (defined('PEAR_ERROR_RETURN')) {
|
||||
return false;
|
||||
}
|
||||
// Serendipity-Patch end
|
||||
/**
|
||||
* PEAR, the PHP Extension and Application Repository
|
||||
*
|
||||
* PEAR class and PEAR_Error class
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Sterling Hughes <sterling@php.net>
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2010 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @since File available since Release 0.1
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* ERROR constants
|
||||
*/
|
||||
define('PEAR_ERROR_RETURN', 1);
|
||||
define('PEAR_ERROR_PRINT', 2);
|
||||
define('PEAR_ERROR_TRIGGER', 4);
|
||||
@@ -37,8 +31,7 @@ define('PEAR_ERROR_CALLBACK', 16);
|
||||
* @deprecated
|
||||
*/
|
||||
define('PEAR_ERROR_EXCEPTION', 32);
|
||||
define('PEAR_ZE2', (function_exists('version_compare') &&
|
||||
version_compare(zend_version(), "2-dev", "ge")));
|
||||
/**#@-*/
|
||||
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
define('OS_WINDOWS', true);
|
||||
@@ -50,15 +43,6 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||
define('PEAR_OS', 'Unix'); // blatant assumption
|
||||
}
|
||||
|
||||
// instant backwards compatibility
|
||||
if (!defined('PATH_SEPARATOR')) {
|
||||
if (OS_WINDOWS) {
|
||||
define('PATH_SEPARATOR', ';');
|
||||
} else {
|
||||
define('PATH_SEPARATOR', ':');
|
||||
}
|
||||
}
|
||||
|
||||
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
||||
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
||||
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||
@@ -82,16 +66,23 @@ $GLOBALS['_PEAR_error_handler_stack'] = array();
|
||||
* destructor, use error_log(), syslog() or something similar.
|
||||
*
|
||||
* IMPORTANT! To use the emulated destructors you need to create the
|
||||
* objects by reference: $obj = new PEAR_child;
|
||||
* objects by reference: $obj =& new PEAR_child;
|
||||
*
|
||||
* @since PHP 4.0.2
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @see http://pear.php.net/manual/
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2006 The PHP Group
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.10.1
|
||||
* @link http://pear.php.net/package/PEAR
|
||||
* @see PEAR_Error
|
||||
* @since Class available since PHP 4.0.2
|
||||
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
|
||||
*/
|
||||
class PEAR
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
/**
|
||||
* Whether to enable internal debug messages.
|
||||
*
|
||||
@@ -142,9 +133,17 @@ class PEAR
|
||||
*/
|
||||
var $_expected_errors = array();
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ constructor
|
||||
/**
|
||||
* List of methods that can be called both statically and non-statically.
|
||||
* @var array
|
||||
*/
|
||||
protected static $bivalentMethods = array(
|
||||
'setErrorHandling' => true,
|
||||
'raiseError' => true,
|
||||
'throwError' => true,
|
||||
'pushErrorHandling' => true,
|
||||
'popErrorHandling' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor. Registers this object in
|
||||
@@ -156,15 +155,17 @@ class PEAR
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function PEAR($error_class = null)
|
||||
function __construct($error_class = null)
|
||||
{
|
||||
$classname = strtolower(get_class($this));
|
||||
if ($this->_debug) {
|
||||
print "PEAR constructor called, class=$classname\n";
|
||||
}
|
||||
|
||||
if ($error_class !== null) {
|
||||
$this->_error_class = $error_class;
|
||||
}
|
||||
|
||||
while ($classname && strcasecmp($classname, "pear")) {
|
||||
$destructor = "_$classname";
|
||||
if (method_exists($this, $destructor)) {
|
||||
@@ -181,8 +182,17 @@ class PEAR
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ destructor
|
||||
/**
|
||||
* Only here for backwards compatibility.
|
||||
* E.g. Archive_Tar calls $this->PEAR() in its constructor.
|
||||
*
|
||||
* @param string $error_class Which class to use for error objects,
|
||||
* defaults to PEAR_Error.
|
||||
*/
|
||||
public function PEAR($error_class = null)
|
||||
{
|
||||
self::__construct($error_class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor (the emulated type of...). Does nothing right now,
|
||||
@@ -201,8 +211,31 @@ class PEAR
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getStaticProperty()
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
if (!isset(self::$bivalentMethods[$method])) {
|
||||
trigger_error(
|
||||
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
|
||||
);
|
||||
}
|
||||
return call_user_func_array(
|
||||
array(get_class(), '_' . $method),
|
||||
array_merge(array($this), $arguments)
|
||||
);
|
||||
}
|
||||
|
||||
public static function __callStatic($method, $arguments)
|
||||
{
|
||||
if (!isset(self::$bivalentMethods[$method])) {
|
||||
trigger_error(
|
||||
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
|
||||
);
|
||||
}
|
||||
return call_user_func_array(
|
||||
array(get_class(), '_' . $method),
|
||||
array_merge(array(null), $arguments)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If you have a class that's mostly/entirely static, and you need static
|
||||
@@ -210,38 +243,45 @@ class PEAR
|
||||
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
|
||||
* You MUST use a reference, or they will not persist!
|
||||
*
|
||||
* @access public
|
||||
* @param string $class The calling classname, to prevent clashes
|
||||
* @param string $var The variable to retrieve.
|
||||
* @return mixed A reference to the variable. If not set it will be
|
||||
* auto initialised to NULL.
|
||||
*/
|
||||
function &getStaticProperty($class, $var)
|
||||
public static function &getStaticProperty($class, $var)
|
||||
{
|
||||
static $properties;
|
||||
if (!isset($properties[$class])) {
|
||||
$properties[$class] = array();
|
||||
}
|
||||
|
||||
if (!array_key_exists($var, $properties[$class])) {
|
||||
$properties[$class][$var] = null;
|
||||
}
|
||||
|
||||
return $properties[$class][$var];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ registerShutdownFunc()
|
||||
|
||||
/**
|
||||
* Use this function to register a shutdown method for static
|
||||
* classes.
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $func The function name (or array of class/method) to call
|
||||
* @param mixed $args The arguments to pass to the function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function registerShutdownFunc($func, $args = array())
|
||||
public static function registerShutdownFunc($func, $args = array())
|
||||
{
|
||||
// if we are called statically, there is a potential
|
||||
// that no shutdown func is registered. Bug #6445
|
||||
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
|
||||
register_shutdown_function("_PEAR_call_destructors");
|
||||
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
|
||||
}
|
||||
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ isError()
|
||||
|
||||
/**
|
||||
* Tell whether a value is a PEAR error.
|
||||
*
|
||||
@@ -250,25 +290,23 @@ class PEAR
|
||||
* only if $code is a string and
|
||||
* $obj->getMessage() == $code or
|
||||
* $code is an integer and $obj->getCode() == $code
|
||||
* @access public
|
||||
*
|
||||
* @return bool true if parameter is an error
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
public static function isError($data, $code = null)
|
||||
{
|
||||
if (is_a($data, 'PEAR_Error')) {
|
||||
if (is_null($code)) {
|
||||
return true;
|
||||
} elseif (is_string($code)) {
|
||||
return $data->getMessage() == $code;
|
||||
} else {
|
||||
return $data->getCode() == $code;
|
||||
}
|
||||
if (!is_a($data, 'PEAR_Error')) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ setErrorHandling()
|
||||
if (is_null($code)) {
|
||||
return true;
|
||||
} elseif (is_string($code)) {
|
||||
return $data->getMessage() == $code;
|
||||
}
|
||||
|
||||
return $data->getCode() == $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how errors generated by this object should be handled.
|
||||
@@ -277,6 +315,9 @@ class PEAR
|
||||
* PEAR objects. If called in an object, setErrorHandling sets
|
||||
* the default behaviour for that object.
|
||||
*
|
||||
* @param object $object
|
||||
* Object the method was called on (non-static mode)
|
||||
*
|
||||
* @param int $mode
|
||||
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
|
||||
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
|
||||
@@ -308,12 +349,12 @@ class PEAR
|
||||
*
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
|
||||
function setErrorHandling($mode = null, $options = null)
|
||||
{
|
||||
if (isset($this) && is_a($this, 'PEAR')) {
|
||||
$setmode = &$this->_default_error_mode;
|
||||
$setoptions = &$this->_default_error_options;
|
||||
protected static function _setErrorHandling(
|
||||
$object, $mode = null, $options = null
|
||||
) {
|
||||
if ($object !== null) {
|
||||
$setmode = &$object->_default_error_mode;
|
||||
$setoptions = &$object->_default_error_options;
|
||||
} else {
|
||||
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
|
||||
@@ -346,9 +387,6 @@ class PEAR
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ expectError()
|
||||
|
||||
/**
|
||||
* This method is used to tell which errors you expect to get.
|
||||
* Expected errors are always returned with error mode
|
||||
@@ -371,12 +409,9 @@ class PEAR
|
||||
} else {
|
||||
array_push($this->_expected_errors, array($code));
|
||||
}
|
||||
return sizeof($this->_expected_errors);
|
||||
return count($this->_expected_errors);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ popExpect()
|
||||
|
||||
/**
|
||||
* This method pops one element off the expected error codes
|
||||
* stack.
|
||||
@@ -388,9 +423,6 @@ class PEAR
|
||||
return array_pop($this->_expected_errors);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _checkDelExpect()
|
||||
|
||||
/**
|
||||
* This method checks unsets an error code if available
|
||||
*
|
||||
@@ -402,8 +434,7 @@ class PEAR
|
||||
function _checkDelExpect($error_code)
|
||||
{
|
||||
$deleted = false;
|
||||
|
||||
foreach ($this->_expected_errors AS $key => $error_array) {
|
||||
foreach ($this->_expected_errors as $key => $error_array) {
|
||||
if (in_array($error_code, $error_array)) {
|
||||
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
|
||||
$deleted = true;
|
||||
@@ -414,12 +445,10 @@ class PEAR
|
||||
unset($this->_expected_errors[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ delExpect()
|
||||
|
||||
/**
|
||||
* This method deletes all occurences of the specified element from
|
||||
* the expected error codes stack.
|
||||
@@ -432,34 +461,26 @@ class PEAR
|
||||
function delExpect($error_code)
|
||||
{
|
||||
$deleted = false;
|
||||
|
||||
if ((is_array($error_code) && (0 != count($error_code)))) {
|
||||
// $error_code is a non-empty array here;
|
||||
// we walk through it trying to unset all
|
||||
// values
|
||||
foreach($error_code as $key => $error) {
|
||||
if ($this->_checkDelExpect($error)) {
|
||||
$deleted = true;
|
||||
} else {
|
||||
$deleted = false;
|
||||
}
|
||||
// $error_code is a non-empty array here; we walk through it trying
|
||||
// to unset all values
|
||||
foreach ($error_code as $key => $error) {
|
||||
$deleted = $this->_checkDelExpect($error) ? true : false;
|
||||
}
|
||||
|
||||
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||
} elseif (!empty($error_code)) {
|
||||
// $error_code comes alone, trying to unset it
|
||||
if ($this->_checkDelExpect($error_code)) {
|
||||
return true;
|
||||
} else {
|
||||
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||
}
|
||||
} else {
|
||||
// $error_code is empty
|
||||
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ raiseError()
|
||||
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||
}
|
||||
|
||||
// $error_code is empty
|
||||
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a wrapper that returns an instance of the
|
||||
@@ -493,12 +514,12 @@ class PEAR
|
||||
* @param bool $skipmsg If true, raiseError will only pass error codes,
|
||||
* the error message parameter will be dropped.
|
||||
*
|
||||
* @access public
|
||||
* @return object a PEAR error object
|
||||
* @see PEAR::setErrorHandling
|
||||
* @since PHP 4.0.5
|
||||
*/
|
||||
function raiseError($message = null,
|
||||
protected static function _raiseError($object,
|
||||
$message = null,
|
||||
$code = null,
|
||||
$mode = null,
|
||||
$options = null,
|
||||
@@ -515,19 +536,26 @@ class PEAR
|
||||
$message = $message->getMessage();
|
||||
}
|
||||
|
||||
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
|
||||
if (
|
||||
$object !== null &&
|
||||
isset($object->_expected_errors) &&
|
||||
count($object->_expected_errors) > 0 &&
|
||||
count($exp = end($object->_expected_errors))
|
||||
) {
|
||||
if ($exp[0] == "*" ||
|
||||
(is_int(reset($exp)) && in_array($code, $exp)) ||
|
||||
(is_string(reset($exp)) && in_array($message, $exp))) {
|
||||
(is_string(reset($exp)) && in_array($message, $exp))
|
||||
) {
|
||||
$mode = PEAR_ERROR_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
// No mode given, try global ones
|
||||
if ($mode === null) {
|
||||
// Class error handler
|
||||
if (isset($this) && isset($this->_default_error_mode)) {
|
||||
$mode = $this->_default_error_mode;
|
||||
$options = $this->_default_error_options;
|
||||
if ($object !== null && isset($object->_default_error_mode)) {
|
||||
$mode = $object->_default_error_mode;
|
||||
$options = $object->_default_error_options;
|
||||
// Global error handler
|
||||
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
|
||||
$mode = $GLOBALS['_PEAR_default_error_mode'];
|
||||
@@ -537,43 +565,50 @@ class PEAR
|
||||
|
||||
if ($error_class !== null) {
|
||||
$ec = $error_class;
|
||||
} elseif (isset($this) && isset($this->_error_class)) {
|
||||
$ec = $this->_error_class;
|
||||
} elseif ($object !== null && isset($object->_error_class)) {
|
||||
$ec = $object->_error_class;
|
||||
} else {
|
||||
$ec = 'PEAR_Error';
|
||||
}
|
||||
if ($skipmsg) {
|
||||
return new $ec($code, $mode, $options, $userinfo);
|
||||
} else {
|
||||
return new $ec($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ throwError()
|
||||
if ($skipmsg) {
|
||||
$a = new $ec($code, $mode, $options, $userinfo);
|
||||
} else {
|
||||
$a = new $ec($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpler form of raiseError with fewer options. In most cases
|
||||
* message, code and userinfo are enough.
|
||||
*
|
||||
* @param string $message
|
||||
* @param mixed $message a text error message or a PEAR error object
|
||||
*
|
||||
* @param int $code a numeric error code (it is up to your class
|
||||
* to define these if you want to use codes)
|
||||
*
|
||||
* @param string $userinfo If you need to pass along for example debug
|
||||
* information, this parameter is meant for that.
|
||||
*
|
||||
* @return object a PEAR error object
|
||||
* @see PEAR::raiseError
|
||||
*/
|
||||
function throwError($message = null,
|
||||
$code = null,
|
||||
$userinfo = null)
|
||||
protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
|
||||
{
|
||||
if (isset($this) && is_a($this, 'PEAR')) {
|
||||
return $this->raiseError($message, $code, null, null, $userinfo);
|
||||
} else {
|
||||
return PEAR::raiseError($message, $code, null, null, $userinfo);
|
||||
if ($object !== null) {
|
||||
$a = &$object->raiseError($message, $code, null, null, $userinfo);
|
||||
return $a;
|
||||
}
|
||||
|
||||
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
|
||||
return $a;
|
||||
}
|
||||
|
||||
// }}}
|
||||
function staticPushErrorHandling($mode, $options = null)
|
||||
public static function staticPushErrorHandling($mode, $options = null)
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||
$stack[] = array($def_mode, $def_options);
|
||||
@@ -606,7 +641,7 @@ class PEAR
|
||||
return true;
|
||||
}
|
||||
|
||||
function staticPopErrorHandling()
|
||||
public static function staticPopErrorHandling()
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
@@ -642,8 +677,6 @@ class PEAR
|
||||
return true;
|
||||
}
|
||||
|
||||
// {{{ pushErrorHandling()
|
||||
|
||||
/**
|
||||
* Push a new error handler on top of the error handler options stack. With this
|
||||
* you can easily override the actual error handler for some code and restore
|
||||
@@ -656,20 +689,20 @@ class PEAR
|
||||
*
|
||||
* @see PEAR::setErrorHandling
|
||||
*/
|
||||
function pushErrorHandling($mode, $options = null)
|
||||
protected static function _pushErrorHandling($object, $mode, $options = null)
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
if (isset($this) && is_a($this, 'PEAR')) {
|
||||
$def_mode = &$this->_default_error_mode;
|
||||
$def_options = &$this->_default_error_options;
|
||||
if ($object !== null) {
|
||||
$def_mode = &$object->_default_error_mode;
|
||||
$def_options = &$object->_default_error_options;
|
||||
} else {
|
||||
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
|
||||
$def_options = &$GLOBALS['_PEAR_default_error_options'];
|
||||
}
|
||||
$stack[] = array($def_mode, $def_options);
|
||||
|
||||
if (isset($this) && is_a($this, 'PEAR')) {
|
||||
$this->setErrorHandling($mode, $options);
|
||||
if ($object !== null) {
|
||||
$object->setErrorHandling($mode, $options);
|
||||
} else {
|
||||
PEAR::setErrorHandling($mode, $options);
|
||||
}
|
||||
@@ -677,9 +710,6 @@ class PEAR
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ popErrorHandling()
|
||||
|
||||
/**
|
||||
* Pop the last error handler used
|
||||
*
|
||||
@@ -687,58 +717,57 @@ class PEAR
|
||||
*
|
||||
* @see PEAR::pushErrorHandling
|
||||
*/
|
||||
function popErrorHandling()
|
||||
protected static function _popErrorHandling($object)
|
||||
{
|
||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||
array_pop($stack);
|
||||
list($mode, $options) = $stack[sizeof($stack) - 1];
|
||||
array_pop($stack);
|
||||
if (isset($this) && is_a($this, 'PEAR')) {
|
||||
$this->setErrorHandling($mode, $options);
|
||||
if ($object !== null) {
|
||||
$object->setErrorHandling($mode, $options);
|
||||
} else {
|
||||
PEAR::setErrorHandling($mode, $options);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ loadExtension()
|
||||
|
||||
/**
|
||||
* OS independant PHP extension load. Remember to take care
|
||||
* OS independent PHP extension load. Remember to take care
|
||||
* on the correct extension name for case sensitive OSes.
|
||||
*
|
||||
* @param string $ext The extension name
|
||||
* @return bool Success or not on the dl() call
|
||||
*/
|
||||
function loadExtension($ext)
|
||||
public static function loadExtension($ext)
|
||||
{
|
||||
if (!extension_loaded($ext)) {
|
||||
// if either returns true dl() will produce a FATAL error, stop that
|
||||
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
|
||||
return false;
|
||||
}
|
||||
if (OS_WINDOWS) {
|
||||
$suffix = '.dll';
|
||||
} elseif (PHP_OS == 'HP-UX') {
|
||||
$suffix = '.sl';
|
||||
} elseif (PHP_OS == 'AIX') {
|
||||
$suffix = '.a';
|
||||
} elseif (PHP_OS == 'OSX') {
|
||||
$suffix = '.bundle';
|
||||
} else {
|
||||
$suffix = '.so';
|
||||
}
|
||||
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
|
||||
if (extension_loaded($ext)) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// if either returns true dl() will produce a FATAL error, stop that
|
||||
if (
|
||||
function_exists('dl') === false ||
|
||||
ini_get('enable_dl') != 1
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OS_WINDOWS) {
|
||||
$suffix = '.dll';
|
||||
} elseif (PHP_OS == 'HP-UX') {
|
||||
$suffix = '.sl';
|
||||
} elseif (PHP_OS == 'AIX') {
|
||||
$suffix = '.a';
|
||||
} elseif (PHP_OS == 'OSX') {
|
||||
$suffix = '.bundle';
|
||||
} else {
|
||||
$suffix = '.so';
|
||||
}
|
||||
|
||||
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
|
||||
}
|
||||
}
|
||||
|
||||
// {{{ _PEAR_call_destructors()
|
||||
if (!function_exists('_PEAR_call_destructors')) {
|
||||
function _PEAR_call_destructors()
|
||||
{
|
||||
global $_PEAR_destructor_object_list;
|
||||
@@ -746,9 +775,13 @@ function _PEAR_call_destructors()
|
||||
sizeof($_PEAR_destructor_object_list))
|
||||
{
|
||||
reset($_PEAR_destructor_object_list);
|
||||
if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {
|
||||
|
||||
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
|
||||
|
||||
if ($destructLifoExists) {
|
||||
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
|
||||
}
|
||||
|
||||
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
|
||||
$classname = get_class($objref);
|
||||
while ($classname) {
|
||||
@@ -767,20 +800,36 @@ function _PEAR_call_destructors()
|
||||
}
|
||||
|
||||
// Now call the shutdown functions
|
||||
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
|
||||
if (
|
||||
isset($GLOBALS['_PEAR_shutdown_funcs']) &&
|
||||
is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
|
||||
!empty($GLOBALS['_PEAR_shutdown_funcs'])
|
||||
) {
|
||||
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
|
||||
call_user_func_array($value[0], $value[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
/**
|
||||
* Standard PEAR error class for PHP 4
|
||||
*
|
||||
* This class is supserseded by {@link PEAR_Exception} in PHP 5
|
||||
*
|
||||
* @category pear
|
||||
* @package PEAR
|
||||
* @author Stig Bakken <ssb@php.net>
|
||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||
* @author Gregory Beaver <cellog@php.net>
|
||||
* @copyright 1997-2006 The PHP Group
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: 1.10.1
|
||||
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
|
||||
* @see PEAR::raiseError(), PEAR::throwError()
|
||||
* @since Class available since PHP 4.0.2
|
||||
*/
|
||||
class PEAR_Error
|
||||
{
|
||||
// {{{ properties
|
||||
|
||||
var $error_message_prefix = '';
|
||||
var $mode = PEAR_ERROR_RETURN;
|
||||
var $level = E_USER_NOTICE;
|
||||
@@ -789,9 +838,6 @@ class PEAR_Error
|
||||
var $userinfo = '';
|
||||
var $backtrace = null;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
|
||||
/**
|
||||
* PEAR_Error constructor
|
||||
*
|
||||
@@ -812,7 +858,7 @@ class PEAR_Error
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
function PEAR_Error($message = 'unknown error', $code = null,
|
||||
function __construct($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
if ($mode === null) {
|
||||
@@ -822,11 +868,16 @@ class PEAR_Error
|
||||
$this->code = $code;
|
||||
$this->mode = $mode;
|
||||
$this->userinfo = $userinfo;
|
||||
if (function_exists("debug_backtrace")) {
|
||||
if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
|
||||
$this->backtrace = debug_backtrace();
|
||||
|
||||
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
|
||||
|
||||
if (!$skiptrace) {
|
||||
$this->backtrace = debug_backtrace();
|
||||
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
|
||||
unset($this->backtrace[0]['object']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode & PEAR_ERROR_CALLBACK) {
|
||||
$this->level = E_USER_NOTICE;
|
||||
$this->callback = $options;
|
||||
@@ -834,20 +885,25 @@ class PEAR_Error
|
||||
if ($options === null) {
|
||||
$options = E_USER_NOTICE;
|
||||
}
|
||||
|
||||
$this->level = $options;
|
||||
$this->callback = null;
|
||||
}
|
||||
|
||||
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||
if (is_null($options) || is_int($options)) {
|
||||
$format = "%s";
|
||||
} else {
|
||||
$format = $options;
|
||||
}
|
||||
|
||||
printf($format, $this->getMessage());
|
||||
}
|
||||
|
||||
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||
trigger_error($this->getMessage(), $this->level);
|
||||
}
|
||||
|
||||
if ($this->mode & PEAR_ERROR_DIE) {
|
||||
$msg = $this->getMessage();
|
||||
if (is_null($options) || is_int($options)) {
|
||||
@@ -860,19 +916,34 @@ class PEAR_Error
|
||||
}
|
||||
die(sprintf($format, $msg));
|
||||
}
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
||||
if (is_callable($this->callback)) {
|
||||
call_user_func($this->callback, $this);
|
||||
}
|
||||
|
||||
if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
|
||||
call_user_func($this->callback, $this);
|
||||
}
|
||||
|
||||
if ($this->mode & PEAR_ERROR_EXCEPTION) {
|
||||
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING);
|
||||
eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);');
|
||||
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
|
||||
eval('$e = new Exception($this->message, $this->code);throw($e);');
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getMode()
|
||||
/**
|
||||
* Only here for backwards compatibility.
|
||||
*
|
||||
* Class "Cache_Error" still uses it, among others.
|
||||
*
|
||||
* @param string $message Message
|
||||
* @param int $code Error code
|
||||
* @param int $mode Error mode
|
||||
* @param mixed $options See __construct()
|
||||
* @param string $userinfo Additional user/debug info
|
||||
*/
|
||||
public function PEAR_Error(
|
||||
$message = 'unknown error', $code = null, $mode = null,
|
||||
$options = null, $userinfo = null
|
||||
) {
|
||||
self::__construct($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error mode from an error object.
|
||||
@@ -880,27 +951,22 @@ class PEAR_Error
|
||||
* @return int error mode
|
||||
* @access public
|
||||
*/
|
||||
function getMode() {
|
||||
function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getCallback()
|
||||
|
||||
/**
|
||||
* Get the callback function/method from an error object.
|
||||
*
|
||||
* @return mixed callback function or object/method array
|
||||
* @access public
|
||||
*/
|
||||
function getCallback() {
|
||||
function getCallback()
|
||||
{
|
||||
return $this->callback;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getMessage()
|
||||
|
||||
|
||||
/**
|
||||
* Get the error message from an error object.
|
||||
*
|
||||
@@ -912,10 +978,6 @@ class PEAR_Error
|
||||
return ($this->error_message_prefix . $this->message);
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
// {{{ getCode()
|
||||
|
||||
/**
|
||||
* Get error code from an error object
|
||||
*
|
||||
@@ -927,9 +989,6 @@ class PEAR_Error
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getType()
|
||||
|
||||
/**
|
||||
* Get the name of this error/exception.
|
||||
*
|
||||
@@ -941,9 +1000,6 @@ class PEAR_Error
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getUserInfo()
|
||||
|
||||
/**
|
||||
* Get additional user-supplied information.
|
||||
*
|
||||
@@ -955,9 +1011,6 @@ class PEAR_Error
|
||||
return $this->userinfo;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getDebugInfo()
|
||||
|
||||
/**
|
||||
* Get additional debug information supplied by the application.
|
||||
*
|
||||
@@ -969,9 +1022,6 @@ class PEAR_Error
|
||||
return $this->getUserInfo();
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ getBacktrace()
|
||||
|
||||
/**
|
||||
* Get the call backtrace from where the error was generated.
|
||||
* Supported with PHP 4.3.0 or newer.
|
||||
@@ -982,15 +1032,15 @@ class PEAR_Error
|
||||
*/
|
||||
function getBacktrace($frame = null)
|
||||
{
|
||||
if (defined('PEAR_IGNORE_BACKTRACE')) {
|
||||
return null;
|
||||
}
|
||||
if ($frame === null) {
|
||||
return $this->backtrace;
|
||||
}
|
||||
return $this->backtrace[$frame];
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ addUserInfo()
|
||||
|
||||
function addUserInfo($info)
|
||||
{
|
||||
if (empty($this->userinfo)) {
|
||||
@@ -1000,8 +1050,10 @@ class PEAR_Error
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ toString()
|
||||
function __toString()
|
||||
{
|
||||
return $this->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a string representation of this object.
|
||||
@@ -1009,7 +1061,8 @@ class PEAR_Error
|
||||
* @return string a string with an object summary
|
||||
* @access public
|
||||
*/
|
||||
function toString() {
|
||||
function toString()
|
||||
{
|
||||
$modes = array();
|
||||
$levels = array(E_USER_NOTICE => 'notice',
|
||||
E_USER_WARNING => 'warning',
|
||||
@@ -1048,8 +1101,6 @@ class PEAR_Error
|
||||
$this->error_message_prefix,
|
||||
$this->userinfo);
|
||||
}
|
||||
|
||||
// }}}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1059,4 +1110,3 @@ class PEAR_Error
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
?>
|
||||
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
|
||||
/**
|
||||
* PEAR_Exception
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category PEAR
|
||||
* @package PEAR_Exception
|
||||
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @link http://pear.php.net/package/PEAR_Exception
|
||||
* @since File available since Release 1.0.0
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base PEAR_Exception Class
|
||||
*
|
||||
* 1) Features:
|
||||
*
|
||||
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
|
||||
* - Definable triggers, shot when exceptions occur
|
||||
* - Pretty and informative error messages
|
||||
* - Added more context info available (like class, method or cause)
|
||||
* - cause can be a PEAR_Exception or an array of mixed
|
||||
* PEAR_Exceptions/PEAR_ErrorStack warnings
|
||||
* - callbacks for specific exception classes and their children
|
||||
*
|
||||
* 2) Ideas:
|
||||
*
|
||||
* - Maybe a way to define a 'template' for the output
|
||||
*
|
||||
* 3) Inherited properties from PHP Exception Class:
|
||||
*
|
||||
* protected $message
|
||||
* protected $code
|
||||
* protected $line
|
||||
* protected $file
|
||||
* private $trace
|
||||
*
|
||||
* 4) Inherited methods from PHP Exception Class:
|
||||
*
|
||||
* __clone
|
||||
* __construct
|
||||
* getMessage
|
||||
* getCode
|
||||
* getFile
|
||||
* getLine
|
||||
* getTraceSafe
|
||||
* getTraceSafeAsString
|
||||
* __toString
|
||||
*
|
||||
* 5) Usage example
|
||||
*
|
||||
* <code>
|
||||
* require_once 'PEAR/Exception.php';
|
||||
*
|
||||
* class Test {
|
||||
* function foo() {
|
||||
* throw new PEAR_Exception('Error Message', ERROR_CODE);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* function myLogger($pear_exception) {
|
||||
* echo $pear_exception->getMessage();
|
||||
* }
|
||||
* // each time a exception is thrown the 'myLogger' will be called
|
||||
* // (its use is completely optional)
|
||||
* PEAR_Exception::addObserver('myLogger');
|
||||
* $test = new Test;
|
||||
* try {
|
||||
* $test->foo();
|
||||
* } catch (PEAR_Exception $e) {
|
||||
* print $e;
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @category PEAR
|
||||
* @package PEAR_Exception
|
||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||
* @author Hans Lellelid <hans@velum.net>
|
||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||
* @author Greg Beaver <cellog@php.net>
|
||||
* @copyright 1997-2009 The Authors
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/PEAR_Exception
|
||||
* @since Class available since Release 1.0.0
|
||||
*/
|
||||
class PEAR_Exception extends Exception
|
||||
{
|
||||
const OBSERVER_PRINT = -2;
|
||||
const OBSERVER_TRIGGER = -4;
|
||||
const OBSERVER_DIE = -8;
|
||||
protected $cause;
|
||||
private static $_observers = array();
|
||||
private static $_uniqueid = 0;
|
||||
private $_trace;
|
||||
|
||||
/**
|
||||
* Supported signatures:
|
||||
* - PEAR_Exception(string $message);
|
||||
* - PEAR_Exception(string $message, int $code);
|
||||
* - PEAR_Exception(string $message, Exception $cause);
|
||||
* - PEAR_Exception(string $message, Exception $cause, int $code);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause);
|
||||
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
|
||||
* - PEAR_Exception(string $message, array $causes);
|
||||
* - PEAR_Exception(string $message, array $causes, int $code);
|
||||
*
|
||||
* @param string $message exception message
|
||||
* @param int|Exception|PEAR_Error|array|null $p2 exception cause
|
||||
* @param int|null $p3 exception code or null
|
||||
*/
|
||||
public function __construct($message, $p2 = null, $p3 = null)
|
||||
{
|
||||
if (is_int($p2)) {
|
||||
$code = $p2;
|
||||
$this->cause = null;
|
||||
} elseif (is_object($p2) || is_array($p2)) {
|
||||
// using is_object allows both Exception and PEAR_Error
|
||||
if (is_object($p2) && !($p2 instanceof Exception)) {
|
||||
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
|
||||
throw new PEAR_Exception(
|
||||
'exception cause must be Exception, ' .
|
||||
'array, or PEAR_Error'
|
||||
);
|
||||
}
|
||||
}
|
||||
$code = $p3;
|
||||
if (is_array($p2) && isset($p2['message'])) {
|
||||
// fix potential problem of passing in a single warning
|
||||
$p2 = array($p2);
|
||||
}
|
||||
$this->cause = $p2;
|
||||
} else {
|
||||
$code = null;
|
||||
$this->cause = null;
|
||||
}
|
||||
parent::__construct($message, $code);
|
||||
$this->signal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an exception observer
|
||||
*
|
||||
* @param mixed $callback - A valid php callback, see php func is_callable()
|
||||
* - A PEAR_Exception::OBSERVER_* constant
|
||||
* - An array(const PEAR_Exception::OBSERVER_*,
|
||||
* mixed $options)
|
||||
* @param string $label The name of the observer. Use this if you want
|
||||
* to remove it later with removeObserver()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function addObserver($callback, $label = 'default')
|
||||
{
|
||||
self::$_observers[$label] = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an exception observer
|
||||
*
|
||||
* @param string $label Name of the observer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function removeObserver($label = 'default')
|
||||
{
|
||||
unset(self::$_observers[$label]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique ID for an observer
|
||||
*
|
||||
* @return int unique identifier for an observer
|
||||
*/
|
||||
public static function getUniqueId()
|
||||
{
|
||||
return self::$_uniqueid++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a signal to all observers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function signal()
|
||||
{
|
||||
foreach (self::$_observers as $func) {
|
||||
if (is_callable($func)) {
|
||||
call_user_func($func, $this);
|
||||
continue;
|
||||
}
|
||||
settype($func, 'array');
|
||||
switch ($func[0]) {
|
||||
case self::OBSERVER_PRINT :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
printf($f, $this->getMessage());
|
||||
break;
|
||||
case self::OBSERVER_TRIGGER :
|
||||
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
|
||||
trigger_error($this->getMessage(), $f);
|
||||
break;
|
||||
case self::OBSERVER_DIE :
|
||||
$f = (isset($func[1])) ? $func[1] : '%s';
|
||||
die(printf($f, $this->getMessage()));
|
||||
break;
|
||||
default:
|
||||
trigger_error('invalid observer type', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return specific error information that can be used for more detailed
|
||||
* error messages or translation.
|
||||
*
|
||||
* This method may be overridden in child exception classes in order
|
||||
* to add functionality not present in PEAR_Exception and is a placeholder
|
||||
* to define API
|
||||
*
|
||||
* The returned array must be an associative array of parameter => value like so:
|
||||
* <pre>
|
||||
* array('name' => $name, 'context' => array(...))
|
||||
* </pre>
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorData()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception that caused this exception to be thrown
|
||||
*
|
||||
* @return Exception|array The context of the exception
|
||||
*/
|
||||
public function getCause()
|
||||
{
|
||||
return $this->cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function must be public to call on caused exceptions
|
||||
*
|
||||
* @param array $causes Array that gets filled.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getCauseMessage(&$causes)
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$cause = array('class' => get_class($this),
|
||||
'message' => $this->message,
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
if (isset($trace[0])) {
|
||||
if (isset($trace[0]['file'])) {
|
||||
$cause['file'] = $trace[0]['file'];
|
||||
$cause['line'] = $trace[0]['line'];
|
||||
}
|
||||
}
|
||||
$causes[] = $cause;
|
||||
if ($this->cause instanceof PEAR_Exception) {
|
||||
$this->cause->getCauseMessage($causes);
|
||||
} elseif ($this->cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => $this->cause->getFile(),
|
||||
'line' => $this->cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
|
||||
$causes[] = array('class' => get_class($this->cause),
|
||||
'message' => $this->cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($this->cause)) {
|
||||
foreach ($this->cause as $cause) {
|
||||
if ($cause instanceof PEAR_Exception) {
|
||||
$cause->getCauseMessage($causes);
|
||||
} elseif ($cause instanceof Exception) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => $cause->getFile(),
|
||||
'line' => $cause->getLine());
|
||||
} elseif (class_exists('PEAR_Error')
|
||||
&& $cause instanceof PEAR_Error
|
||||
) {
|
||||
$causes[] = array('class' => get_class($cause),
|
||||
'message' => $cause->getMessage(),
|
||||
'file' => 'unknown',
|
||||
'line' => 'unknown');
|
||||
} elseif (is_array($cause) && isset($cause['message'])) {
|
||||
// PEAR_ErrorStack warning
|
||||
$causes[] = array(
|
||||
'class' => $cause['package'],
|
||||
'message' => $cause['message'],
|
||||
'file' => isset($cause['context']['file']) ?
|
||||
$cause['context']['file'] :
|
||||
'unknown',
|
||||
'line' => isset($cause['context']['line']) ?
|
||||
$cause['context']['line'] :
|
||||
'unknown',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a backtrace and return it
|
||||
*
|
||||
* @return array Backtrace
|
||||
*/
|
||||
public function getTraceSafe()
|
||||
{
|
||||
if (!isset($this->_trace)) {
|
||||
$this->_trace = $this->getTrace();
|
||||
if (empty($this->_trace)) {
|
||||
$backtrace = debug_backtrace();
|
||||
$this->_trace = array($backtrace[count($backtrace)-1]);
|
||||
}
|
||||
}
|
||||
return $this->_trace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first class of the backtrace
|
||||
*
|
||||
* @return string Class name
|
||||
*/
|
||||
public function getErrorClass()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['class'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first method of the backtrace
|
||||
*
|
||||
* @return string Method/function name
|
||||
*/
|
||||
public function getErrorMethod()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
return $trace[0]['function'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the exception to a string (HTML or plain text)
|
||||
*
|
||||
* @return string String representation
|
||||
*
|
||||
* @see toHtml()
|
||||
* @see toText()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (isset($_SERVER['REQUEST_URI'])) {
|
||||
return $this->toHtml();
|
||||
}
|
||||
return $this->toText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a HTML representation of the exception
|
||||
*
|
||||
* @return string HTML code
|
||||
*/
|
||||
public function toHtml()
|
||||
{
|
||||
$trace = $this->getTraceSafe();
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
|
||||
foreach ($causes as $i => $cause) {
|
||||
$html .= '<tr><td colspan="3" style="background: #ff9999">'
|
||||
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
|
||||
. htmlspecialchars($cause['message'])
|
||||
. ' in <b>' . $cause['file'] . '</b> '
|
||||
. 'on line <b>' . $cause['line'] . '</b>'
|
||||
. "</td></tr>\n";
|
||||
}
|
||||
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
|
||||
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
|
||||
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
|
||||
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
|
||||
|
||||
foreach ($trace as $k => $v) {
|
||||
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
|
||||
. '<td>';
|
||||
if (!empty($v['class'])) {
|
||||
$html .= $v['class'] . $v['type'];
|
||||
}
|
||||
$html .= $v['function'];
|
||||
$args = array();
|
||||
if (!empty($v['args'])) {
|
||||
foreach ($v['args'] as $arg) {
|
||||
if (is_null($arg)) {
|
||||
$args[] = 'null';
|
||||
} else if (is_array($arg)) {
|
||||
$args[] = 'Array';
|
||||
} else if (is_object($arg)) {
|
||||
$args[] = 'Object('.get_class($arg).')';
|
||||
} else if (is_bool($arg)) {
|
||||
$args[] = $arg ? 'true' : 'false';
|
||||
} else if (is_int($arg) || is_double($arg)) {
|
||||
$args[] = $arg;
|
||||
} else {
|
||||
$arg = (string)$arg;
|
||||
$str = htmlspecialchars(substr($arg, 0, 16));
|
||||
if (strlen($arg) > 16) {
|
||||
$str .= '…';
|
||||
}
|
||||
$args[] = "'" . $str . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
$html .= '(' . implode(', ', $args) . ')'
|
||||
. '</td>'
|
||||
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
|
||||
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
|
||||
. '</td></tr>' . "\n";
|
||||
}
|
||||
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
|
||||
. '<td>{main}</td>'
|
||||
. '<td> </td></tr>' . "\n"
|
||||
. '</table>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates text representation of the exception and stack trace
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toText()
|
||||
{
|
||||
$causes = array();
|
||||
$this->getCauseMessage($causes);
|
||||
$causeMsg = '';
|
||||
foreach ($causes as $i => $cause) {
|
||||
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
|
||||
. $cause['message'] . ' in ' . $cause['file']
|
||||
. ' on line ' . $cause['line'] . "\n";
|
||||
}
|
||||
return $causeMsg . $this->getTraceAsString();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* This is only meant for PHP 5 to get rid of certain strict warning
|
||||
* that doesn't get hidden since it's in the shutdown function
|
||||
*/
|
||||
class PEAR5
|
||||
{
|
||||
/**
|
||||
* If you have a class that's mostly/entirely static, and you need static
|
||||
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
|
||||
* You MUST use a reference, or they will not persist!
|
||||
*
|
||||
* @access public
|
||||
* @param string $class The calling classname, to prevent clashes
|
||||
* @param string $var The variable to retrieve.
|
||||
* @return mixed A reference to the variable. If not set it will be
|
||||
* auto initialised to NULL.
|
||||
*/
|
||||
static function &getStaticProperty($class, $var)
|
||||
{
|
||||
static $properties;
|
||||
if (!isset($properties[$class])) {
|
||||
$properties[$class] = array();
|
||||
}
|
||||
|
||||
if (!array_key_exists($var, $properties[$class])) {
|
||||
$properties[$class][$var] = null;
|
||||
}
|
||||
|
||||
return $properties[$class][$var];
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
Smarty is supported only in PHP 4.0.6 or later.
|
||||
|
||||
Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include
|
||||
the path to the PEAR libraries in your php include_path. Config_file.class.php
|
||||
uses the PEAR library for its error handling routines. PEAR comes with the PHP
|
||||
distribution. Unix users check /usr/local/lib/php, windows users check
|
||||
C:/php/pear.
|
||||
+126
-419
@@ -1,458 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
0. Additional Definitions.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
4. Combined Works.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
d) Do one of the following:
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
5. Combined Libraries.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,284 +0,0 @@
|
||||
QUESTION INDEX
|
||||
--------------
|
||||
|
||||
GENERAL
|
||||
|
||||
Q: What is Smarty?
|
||||
Q: What's the difference between Smarty and other template engines?
|
||||
Q: What do you mean "Compiled PHP Scripts" ?
|
||||
Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
|
||||
Q: Why does smarty have a built in cache? Wouldn't it be better to handle this
|
||||
in a separate class?
|
||||
Q: Is Smarty faster than <insert other PHP template engine>?
|
||||
Q: How can I be sure to get the best performance from Smarty?
|
||||
Q: Do you have a mailing list?
|
||||
Q: Can you change the mailing list so reply-to sends to the list and not the
|
||||
user?
|
||||
|
||||
TROUBLESHOOTING
|
||||
|
||||
Q: Smarty doesn't work.
|
||||
Q: I get the following error when running Smarty:
|
||||
Warning: Smarty error: problem creating directory "templates_c/239/239105369"
|
||||
in /path/to/Smarty.class.php on line 542
|
||||
Q: I get the following error when running Smarty:
|
||||
Warning: Wrong parameter count for preg_replace() in
|
||||
Smarty.class.php on line 371
|
||||
Q: I get this error when passing variables to {include}:
|
||||
Fatal error: Call to undefined function: get_defined_vars() in
|
||||
/path/to/Smarty/templates_c/index.tpl.php on line 8
|
||||
Q: I get PHP errors in my {if} tag logic.
|
||||
Q: I'm changing my php code and/or templates, and my results are not getting
|
||||
updated.
|
||||
Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
|
||||
also zero length.
|
||||
Q: The template goes into an infinite loop when I include included templates
|
||||
that pass local variables
|
||||
Q: Javascript is causing Smarty errors in my templates.
|
||||
Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
|
||||
|
||||
MISC
|
||||
|
||||
Q: Can I use Macromedia's Dreamweaver to edit my templates?
|
||||
Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
|
||||
HREF link. How do I get around this?
|
||||
|
||||
HOWTO
|
||||
|
||||
Q: How do I generate different cache files per template based on arguments
|
||||
passed to the page?
|
||||
Q: How do I pass a template variable as a parameter? {function param={$varname}}
|
||||
does not work.
|
||||
Q: How do I include cached template(s) within a non-cached template?
|
||||
|
||||
|
||||
GENERAL
|
||||
-------
|
||||
|
||||
Q: What is Smarty?
|
||||
A: Smarty is a template engine for PHP... but be aware this isn't just another
|
||||
PHP template engine. It's much more than that.
|
||||
|
||||
Q: What's the difference between Smarty and other template engines?
|
||||
A: Most other template engines for PHP provide basic variable substitution and
|
||||
dynamic block functionality. Smarty takes a step further to be a "smart"
|
||||
template engine, adding features such as configuration files, template
|
||||
functions, variable modifiers (see the docs!) and making all of this
|
||||
functionality as easy as possible to use for both programmers and template
|
||||
designers. Smarty also compiles the templates into PHP scripts, eliminating
|
||||
the need to parse the templates on every invocation, making Smarty extremely
|
||||
scalable and manageable for large application needs.
|
||||
|
||||
Q: What do you mean "Compiled PHP Scripts" ?
|
||||
A: Smarty reads the template files and creates PHP scripts from them. Once
|
||||
these PHP scripts are created, Smarty executes these, never having to parse
|
||||
the template files again. If you change a template file, Smarty will
|
||||
recreate the PHP script for it. All this is done automatically by Smarty.
|
||||
Template designers never need to mess with the generated PHP scripts or even
|
||||
know of their existance. (NOTE: you can turn off this compile checking step
|
||||
in Smarty for increased performance.)
|
||||
|
||||
Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
|
||||
A: You certainly can, and we highly recommend it! What PHPA does is caches
|
||||
compiled bytecode of your PHP scripts in shared memory or in a file. This
|
||||
speeds up server response and saves the compilation step. Smarty creates PHP
|
||||
scripts, which PHPA will cache nicely. Now, Smarty's built-in cache is
|
||||
something completely different. It caches the _output_ of the template
|
||||
contents. For example, if you have a template that requires several database
|
||||
queries, Smarty can cache this output, saving the need to call the database
|
||||
every time. Smarty and PHPA (or Zend Cache) complement each other nicely. If
|
||||
performance is of the utmost importance, we would recommend using one of
|
||||
these with any PHP application, using Smarty or not. As you can see in the
|
||||
benchmarks, Smartys performance _really_ excels in combination with a PHP
|
||||
accelerator.
|
||||
|
||||
Q: Why does Smarty have a built in cache? Wouldn't it be better to handle this
|
||||
in a separate class?
|
||||
A: Smarty's caching functionality is tightly integrated with the template
|
||||
engine, making it quite a bit more flexible than a simple caching wrapper.
|
||||
For instance, you can cache select portions of a template page. Let's say
|
||||
you have a polling box on your site. With Smarty, you can leave the poll
|
||||
dynamic and cache the rest of the page. You can also pass templates
|
||||
multiple cache ids, meaning that a template can have several caches
|
||||
depending on URL, cookies, etc.
|
||||
|
||||
Q: Is Smarty faster than <insert other PHP template engine>?
|
||||
A: See the benchmark page for some performance comparisons. Smarty's approach
|
||||
to templates is a bit different from some languages: it compiles templates
|
||||
into PHP scripts instead of parsing them on each invocation. This usually
|
||||
results in great performance gains, especially with complex templates.
|
||||
Coupled with the built-in caching of Smarty templates, the performance is
|
||||
outstanding.
|
||||
|
||||
Q: How can I be sure to get the best performance from Smarty?
|
||||
A: Be sure you set $compile_check=false once your templates are initially
|
||||
compiled. This will skip the unneeded step of testing if the template has
|
||||
changed since it was last compiled. If you have complex pages that don't
|
||||
change too often, turn on the caching engine and adjust your application so
|
||||
it doesn't do unnecessary work (like db calls) if a cached page is
|
||||
available. See the documentation for examples.
|
||||
|
||||
Q: Do you have a mailing list?
|
||||
A: We have a few mailing lists. "general" for you to share your ideas or ask
|
||||
questions, "dev" for those interested in the development efforts of Smarty,
|
||||
and "cvs" for those that would like to track the updates made in the cvs
|
||||
repository.
|
||||
|
||||
send a blank e-mail message to:
|
||||
smarty-general-subscribe@lists.php.net (subscribe to the general list)
|
||||
smarty-general-unsubscribe@lists.php.net (unsubscribe from the general list)
|
||||
smarty-general-digest-subscribe@lists.php.net (subscribe to digest)
|
||||
smarty-general-digest-unsubscribe@lists.php.net (unsubscribe from digest)
|
||||
smarty-dev-subscribe@lists.php.net (subscribe to the dev list)
|
||||
smarty-dev-unsubscribe@lists.php.net (unsubscribe from the dev list)
|
||||
smarty-cvs-subscribe@lists.php.net (subscribe to the cvs list)
|
||||
smarty-cvs-unsubscribe@lists.php.net (unsubscribe from the cvs list)
|
||||
You can also browse the mailing list archives at
|
||||
http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
|
||||
|
||||
|
||||
|
||||
Q: Can you change the mailing list so Reply-To sends to the list and not the
|
||||
user?
|
||||
A: Yes we could, but no we won't. Use "Reply-All" in your e-mail client to send
|
||||
to the list. http://www.unicom.com/pw/reply-to-harmful.html
|
||||
|
||||
TROUBLESHOOTING
|
||||
---------------
|
||||
|
||||
Q: Smarty doesn't work.
|
||||
A: You must be using PHP 4.0.6 or later if you use any version of Smarty
|
||||
past 2.0.1. Read the BUGS file for more info.
|
||||
|
||||
Q: I get the following error when running Smarty:
|
||||
Warning: Smarty error: problem creating directory "templates_c/239/239105369"
|
||||
in /path/to/Smarty.class.php on line 542
|
||||
A: Your web server user does not have permission to write to the templates_c
|
||||
directory, or is unable to create the templates_c directory. Be sure the
|
||||
templates_c directory exists in the location defined in Smarty.class.php,
|
||||
and the web server user can write to it. If you do not know the web server
|
||||
user, chmod 777 the templates_c directory, reload the page, then check the
|
||||
file ownership of the files created in templates_c. Or, you can check the
|
||||
httpd.conf (usually in /usr/local/apache/conf) file for this setting:
|
||||
User nobody
|
||||
Group nobody
|
||||
|
||||
Q: I get the following error when running Smarty: Warning: Wrong parameter
|
||||
count for preg_replace() in Smarty.class.php on line 371
|
||||
A: preg_replace had a parameter added in PHP 4.0.2 that Smarty
|
||||
requires. Upgrade to at least 4.0.6 to fix all known PHP issues with
|
||||
Smarty.
|
||||
|
||||
Q: I get this error when passing variables to {include}:
|
||||
Fatal error: Call to undefined function: get_defined_vars() in
|
||||
/path/to/Smarty/templates_c/index.tpl.php on line 8
|
||||
A: get_defined_vars() was added to PHP 4.0.4. If you plan on passing
|
||||
variables to included templates, you will need PHP 4.0.6 or later.
|
||||
|
||||
Q: I get PHP errors in my {if} tag logic.
|
||||
A: All conditional qualifiers must be separated by spaces. This syntax will not
|
||||
work: {if $name=="Wilma"} You must instead do this: {if $name == "Wilma"}.
|
||||
The reason for this is syntax ambiguity. Both "==" and "eq" are equivalent
|
||||
in the template parser, so something like {if $nameeq"Wilma"} wouldn't be
|
||||
parsable by the tokenizer.
|
||||
|
||||
Q: I'm changing my php code and/or templates, and my results are not getting
|
||||
updated.
|
||||
A: This may be the result of your compile or cache settings. If you are
|
||||
changing your php code, your templates will not necessarily get recompiled
|
||||
to reflect the changes. Use $force_compile during develpment to avoid these
|
||||
situations. Also turn off caching during development when you aren't
|
||||
specifically testing it. You can also remove everything from your
|
||||
compile_dir and cache_dir and reload the page to be sure everything gets
|
||||
regenerated.
|
||||
|
||||
Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
|
||||
also zero length.
|
||||
A: There seems to be a problem with some W2k machines and exclusive file
|
||||
locking. Comment out the flock() call in _write_file to get around this,
|
||||
although be aware this could possibly cause a problem with simultaneous
|
||||
writes to a file, especially with caching turned on. NOTE: As of Smarty
|
||||
1.4.0, a workaround was put in place that should solve this.
|
||||
|
||||
Q: The template goes into an infinite loop when I include included templates
|
||||
that pass local variables
|
||||
A: This was fixed in 1.3.2 (new global attribute)
|
||||
|
||||
Q: Javascript is causing Smarty errors in my templates.
|
||||
A: Surround your javascript with {literal}{/literal} tags. See the docs.
|
||||
|
||||
Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
|
||||
A: Use $smarty->use_sub_dirs = false when running php in safe mode.
|
||||
|
||||
MISC
|
||||
----
|
||||
|
||||
Q: Can I use Macromedia's Dreamweaver to edit my templates?
|
||||
A: Certainly. You might want to change your tag delimiters from {} to something
|
||||
that resembles valid HTML, like <!--{ }--> or <{ }> or something similar.
|
||||
This way the editor won't view the template tags as errors.
|
||||
|
||||
Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
|
||||
HREF link. How do I get around this?
|
||||
A: In Edit - Properties - Rewrite HTML you can specify if Dreamweaver should
|
||||
change special letters to %-equivalent or not. The default is on which
|
||||
produces this error.
|
||||
|
||||
HOWTO
|
||||
-----
|
||||
|
||||
Q: How do I generate different cache files per template based on arguments
|
||||
passed to the page?
|
||||
A: Use your $REQUEST_URI as the cache_id when fetching the page:
|
||||
|
||||
global $REQUEST_URI; // if not already present
|
||||
$smarty->display('index.tpl',$REQUEST_URI);
|
||||
|
||||
This will create a separate cache file for each unique URL when you call
|
||||
index.tpl. See the documentation for display() and fetch()
|
||||
|
||||
Q: How do I pass a template variable as a parameter? {function param={$varname}}
|
||||
does not work.
|
||||
A: {function param=$varname} (You cannot nest template delimiters.)
|
||||
|
||||
Q: How do I include cached template(s) within a non-cached template?
|
||||
A: One way to do it:
|
||||
|
||||
$smarty->caching = true;
|
||||
$tpl1 = $smarty->fetch("internal1.tpl");
|
||||
$tpl2 = $smarty->fetch("internal2.tpl");
|
||||
$tpl3 = $smarty->fetch("internal3.tpl");
|
||||
|
||||
$smarty->assign("tpl1_contents",$tpl1);
|
||||
$smarty->assign("tpl2_contents",$tpl2);
|
||||
$smarty->assign("tpl3_contents",$tpl3);
|
||||
|
||||
$smarty->caching = false;
|
||||
$smarty->display('index.tpl');
|
||||
|
||||
index.tpl
|
||||
---------
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>{$tpl1_contents}</td>
|
||||
<td>{$tpl2_contents}</td>
|
||||
<td>{$tpl3_contents}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
Another approach:
|
||||
|
||||
You could write a custom insert function to fetch your internal
|
||||
templates:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>{insert name=fetch_tpl tpl="internal1.tpl"}</td>
|
||||
<td>{insert name=fetch_tpl tpl="internal2.tpl"}</td>
|
||||
<td>{insert name=fetch_tpl tpl="internal3.tpl"}</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -0,0 +1,35 @@
|
||||
In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
|
||||
is done at compile time and the parent and child templates are compiled in a single compiled template.
|
||||
{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because
|
||||
it could be used in other context where the {block} extended with a different result. For that reasion
|
||||
the compiled code of {include} subtemplates gets also merged in compiled inheritance template.
|
||||
|
||||
Merging the code into a single compile template has some drawbacks.
|
||||
1. You could not use variable file names in {include} Smarty would use the {include} of compilation time.
|
||||
2. You could not use individual compile_id in {include}
|
||||
3. Seperate caching of subtemplate was not possible
|
||||
4. Any change of the template directory structure between calls was not necessarily seen.
|
||||
|
||||
Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out
|
||||
that a couple of users did use some of above and now got exceptions.
|
||||
|
||||
To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes.
|
||||
For most backward compatibility its default setting is true.
|
||||
With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases
|
||||
could be rejected by exception.
|
||||
|
||||
|
||||
If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.
|
||||
You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option.
|
||||
{include file='foo.bar' inline}
|
||||
|
||||
1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo;
|
||||
2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the
|
||||
global compile_id as well $smarty->compile_id = $bar;
|
||||
3. If call templates with different template_dir configurations and a parent could same named child template from different folders
|
||||
you must make the folder name part of the compile_id.
|
||||
|
||||
|
||||
In the upcomming major release Smarty 3.2 inheritance will no longer be a compile time process.
|
||||
All restrictions will be then removed.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
REQUIREMENTS:
|
||||
|
||||
Smarty requires PHP 4.0.6 or later.
|
||||
See the on-line documentation for complete install instructions.
|
||||
|
||||
INSTALLATION (quick):
|
||||
|
||||
* copy the files under the libs/ directory to a directory that is in your PHP
|
||||
include_path, or set the SMARTY_DIR constant and put them in this directory.
|
||||
(if you upgrade from versions before 2.5.0 be aware that up to Smarty 2.4.2
|
||||
all necessary files where in the distribution's root directory, but are now
|
||||
in libs/.)
|
||||
|
||||
* for each application using Smarty, create a "templates", "configs", and a
|
||||
"templates_c" directory, be sure to set the appropriate directory settings in
|
||||
Smarty for them. If they are located in the same directory as your
|
||||
application, they shouldn't need to be modified. Be sure the "templates_c"
|
||||
directory is writable by your web server user (usually nobody). chown
|
||||
nobody:nobody templates_c; chmod 700 templates_c You can also chmod 777 this
|
||||
directory, but be aware of security issues for multi-user systems. If you are
|
||||
using Smarty's built-in caching, create a "cache" directory and also chown
|
||||
nobody:nobody.
|
||||
|
||||
* setup your php and template files. A good working example is in the on-line
|
||||
documentation.
|
||||
|
||||
* TECHNICAL NOTE: If you do not have access to the php.ini file, you can change
|
||||
non-server settings (such as your include_path) with the ini_set() command.
|
||||
example: ini_set("include_path",".:/usr/local/lib/php");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
|
||||
|
||||
This file contains a brief description of new features which have been added to Smarty 3.1
|
||||
|
||||
Smarty 3.1.22
|
||||
|
||||
Namespace support within templates
|
||||
==================================
|
||||
Within templates you can now use namespace specifications on:
|
||||
- Constants like foo\bar\FOO
|
||||
- Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo()
|
||||
- PHP function names like foo\bar\baz()
|
||||
|
||||
Security
|
||||
========
|
||||
- disable special $smarty variable -
|
||||
The Smarty_Security class has the new property $disabled_special_smarty_vars.
|
||||
It's an array which can be loaded with the $smarty special variable names like
|
||||
'template_object', 'template', 'current_dir' and others which will be disabled.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- limit template nesting -
|
||||
Property $max_template_nesting of Smarty_Security does set the maximum template nesting level.
|
||||
The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded
|
||||
an Exception will be thrown. The default setting is 0 which does disable this check.
|
||||
|
||||
- trusted static methods -
|
||||
The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods.
|
||||
It's an nested array of trusted class and method names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('method_1', 'method_2'), // allowed methods
|
||||
'class_2' => array(), // all methods of class allowed
|
||||
)
|
||||
To disable access for all methods of all classes set $trusted_static_methods = null;
|
||||
The default value is an empty array() which does enables all methods of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted static properties -
|
||||
The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties.
|
||||
It's an nested array of trusted class and property names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
|
||||
'class_2' => array(), // all properties of class allowed
|
||||
}
|
||||
To disable access for all properties of all classes set $trusted_static_properties = null;
|
||||
The default value is an empty array() which does enables all properties of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted constants .
|
||||
The Smarty_Security class has the new property $trusted_constants to restrict access to constants.
|
||||
It's an array of trusted constant names.
|
||||
Format:
|
||||
array (
|
||||
'SMARTY_DIR' , // allowed constant
|
||||
}
|
||||
If the array is empty (default) the usage of constants can be controlled with the
|
||||
Smarty_Security::$allow_constants property (default true)
|
||||
|
||||
|
||||
|
||||
Compiled Templates
|
||||
==================
|
||||
Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html
|
||||
property and creates different compiled templates files depending on the setting.
|
||||
|
||||
Same applies to config files and the $config_overwrite, $config_booleanize and
|
||||
$config_read_hidden properties.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
The layout of the debug window has been changed for better readability
|
||||
|
||||
New class constants
|
||||
Smarty::DEBUG_OFF
|
||||
Smarty::DEBUG_ON
|
||||
Smarty::DEBUG_INDIVIDUAL
|
||||
have been introduced for setting the $debugging property.
|
||||
|
||||
Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual gebug window.
|
||||
|
||||
.
|
||||
|
||||
+553
-65
@@ -1,86 +1,574 @@
|
||||
Smarty 3.x
|
||||
|
||||
NAME:
|
||||
Author: Monte Ohrt <monte at ohrt dot com >
|
||||
Author: Uwe Tews
|
||||
|
||||
Smarty - the PHP compiling template engine
|
||||
AN INTRODUCTION TO SMARTY 3
|
||||
|
||||
VERSION: 2.6.26
|
||||
NOTICE FOR 3.1 release:
|
||||
|
||||
AUTHORS:
|
||||
|
||||
Monte Ohrt <monte at ohrt dot com>
|
||||
Andrei Zmievski <andrei@php.net>
|
||||
Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
|
||||
|
||||
MAILING LISTS:
|
||||
NOTICE for 3.0.5 release:
|
||||
|
||||
We have a few mailing lists. "discussion" for you to share your ideas or ask
|
||||
questions, "developers" for those interested in the development efforts of Smarty,
|
||||
and "svn" for those that would like to track the updates made in the svn
|
||||
repository.
|
||||
Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
|
||||
|
||||
send a blank e-mail message to:
|
||||
smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list)
|
||||
smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list)
|
||||
smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest)
|
||||
smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest)
|
||||
smarty-developers-subscribe@googlecode.com (subscribe to the dev list)
|
||||
smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list)
|
||||
smarty-svn-subscribe@googlecode.com (subscribe to the svn list)
|
||||
smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list)
|
||||
$smarty->error_reporting = E_ALL & ~E_NOTICE;
|
||||
|
||||
You can also browse the mailing list archives at
|
||||
http://groups.google.com/group/smarty-discussion
|
||||
http://groups.google.com/group/smarty-developers
|
||||
NOTICE for 3.0 release:
|
||||
|
||||
and the OLD list archives at
|
||||
http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
|
||||
IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
|
||||
We felt it is better to make these now instead of after a 3.0 release, then have to
|
||||
immediately deprecate APIs in 3.1. Online documentation has been updated
|
||||
to reflect these changes. Specifically:
|
||||
|
||||
SYNOPSIS:
|
||||
---- API CHANGES RC4 -> 3.0 ----
|
||||
|
||||
require("Smarty.class.php");
|
||||
$smarty->register->*
|
||||
$smarty->unregister->*
|
||||
$smarty->utility->*
|
||||
$samrty->cache->*
|
||||
|
||||
$smarty = new Smarty;
|
||||
Have all been changed to local method calls such as:
|
||||
|
||||
$smarty->assign("Title","My Homepage");
|
||||
$smarty->assign("Names",array("John","Gary","Gregg","James"));
|
||||
$smarty->clearAllCache()
|
||||
$smarty->registerFoo()
|
||||
$smarty->unregisterFoo()
|
||||
$smarty->testInstall()
|
||||
etc.
|
||||
|
||||
$smarty->display("index.tpl");
|
||||
Registration of function, block, compiler, and modifier plugins have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerPlugin(...)
|
||||
$smarty->unregisterPlugin(...)
|
||||
|
||||
Registration of pre, post, output and variable filters have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerFilter(...)
|
||||
$smarty->unregisterFilter(...)
|
||||
|
||||
Please refer to the online documentation for all specific changes:
|
||||
|
||||
http://www.smarty.net/documentation
|
||||
|
||||
----
|
||||
|
||||
The Smarty 3 API has been refactored to a syntax geared
|
||||
for consistency and modularity. The Smarty 2 API syntax is still supported, but
|
||||
will throw a deprecation notice. You can disable the notices, but it is highly
|
||||
recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
|
||||
through an extra rerouting wrapper.
|
||||
|
||||
Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
|
||||
all Smarty properties now have getters and setters. So for example, the property
|
||||
$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
|
||||
retrieved with $smarty->getCacheDir().
|
||||
|
||||
Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
|
||||
just duplicate functions of the now available "get*" methods.
|
||||
|
||||
Here is a rundown of the Smarty 3 API:
|
||||
|
||||
$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->isCached($template, $cache_id = null, $compile_id = null)
|
||||
$smarty->createData($parent = null)
|
||||
$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->enableSecurity()
|
||||
$smarty->disableSecurity()
|
||||
$smarty->setTemplateDir($template_dir)
|
||||
$smarty->addTemplateDir($template_dir)
|
||||
$smarty->templateExists($resource_name)
|
||||
$smarty->loadPlugin($plugin_name, $check = true)
|
||||
$smarty->loadFilter($type, $name)
|
||||
$smarty->setExceptionHandler($handler)
|
||||
$smarty->addPluginsDir($plugins_dir)
|
||||
$smarty->getGlobal($varname = null)
|
||||
$smarty->getRegisteredObject($name)
|
||||
$smarty->getDebugTemplate()
|
||||
$smarty->setDebugTemplate($tpl_name)
|
||||
$smarty->assign($tpl_var, $value = null, $nocache = false)
|
||||
$smarty->assignGlobal($varname, $value = null, $nocache = false)
|
||||
$smarty->assignByRef($tpl_var, &$value, $nocache = false)
|
||||
$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
|
||||
$smarty->appendByRef($tpl_var, &$value, $merge = false)
|
||||
$smarty->clearAssign($tpl_var)
|
||||
$smarty->clearAllAssign()
|
||||
$smarty->configLoad($config_file, $sections = null)
|
||||
$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
|
||||
$smarty->getConfigVariable($variable)
|
||||
$smarty->getStreamVariable($variable)
|
||||
$smarty->getConfigVars($varname = null)
|
||||
$smarty->clearConfig($varname = null)
|
||||
$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
|
||||
$smarty->clearAllCache($exp_time = null, $type = null)
|
||||
$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
|
||||
|
||||
$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
|
||||
|
||||
$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
|
||||
|
||||
$smarty->registerFilter($type, $function_name)
|
||||
$smarty->registerResource($resource_type, $function_names)
|
||||
$smarty->registerDefaultPluginHandler($function_name)
|
||||
$smarty->registerDefaultTemplateHandler($function_name)
|
||||
|
||||
$smarty->unregisterPlugin($type, $tag)
|
||||
$smarty->unregisterObject($object_name)
|
||||
$smarty->unregisterFilter($type, $function_name)
|
||||
$smarty->unregisterResource($resource_type)
|
||||
|
||||
$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
|
||||
$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
|
||||
$smarty->testInstall()
|
||||
|
||||
// then all the getters/setters, available for all properties. Here are a few:
|
||||
|
||||
$caching = $smarty->getCaching(); // get $smarty->caching
|
||||
$smarty->setCaching(true); // set $smarty->caching
|
||||
$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
|
||||
$smarty->setCacheId($id); // set $smarty->cache_id
|
||||
$debugging = $smarty->getDebugging(); // get $smarty->debugging
|
||||
|
||||
|
||||
DESCRIPTION:
|
||||
FILE STRUCTURE
|
||||
|
||||
What is Smarty?
|
||||
The Smarty 3 file structure is similar to Smarty 2:
|
||||
|
||||
Smarty is a template engine for PHP. Many other template engines for PHP
|
||||
provide basic variable substitution and dynamic block functionality.
|
||||
Smarty takes a step further to be a "smart" template engine, adding
|
||||
features such as configuration files, template functions, and variable
|
||||
modifiers, and making all of this functionality as easy as possible to
|
||||
use for both programmers and template designers. Smarty also converts
|
||||
the templates into PHP scripts, eliminating the need to parse the
|
||||
templates on every invocation. This makes Smarty extremely scalable and
|
||||
manageable for large application needs.
|
||||
/libs/
|
||||
Smarty.class.php
|
||||
/libs/sysplugins/
|
||||
internal.*
|
||||
/libs/plugins/
|
||||
function.mailto.php
|
||||
modifier.escape.php
|
||||
...
|
||||
|
||||
Some of Smarty's features:
|
||||
A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
|
||||
not need to change any files here. The /libs/plugins/ folder is where Smarty
|
||||
plugins are located. You can add your own here, or create a separate plugin
|
||||
directory, just the same as Smarty 2. You will still need to create your own
|
||||
/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
|
||||
/templates_c/ are writable.
|
||||
|
||||
* it is extremely fast
|
||||
* no template parsing overhead, only compiles once.
|
||||
* it is smart about recompiling only the template files that have
|
||||
changed.
|
||||
* the template language is remarkably extensible via the plugin
|
||||
architecture.
|
||||
* configurable template delimiter tag syntax, so you can use
|
||||
{}, {{}}, <!--{}-->, or whatever you like.
|
||||
* built-in caching of template output.
|
||||
* arbitrary template sources (filesystem, databases, etc.)
|
||||
* template if/elseif/else/endif constructs are passed to the PHP parser,
|
||||
so the if syntax can be as simple or as complex as you like.
|
||||
* unlimited nesting of sections, conditionals, etc. allowed
|
||||
* it is possible to embed PHP code right in your template files,
|
||||
although not recommended and doubtfully needed since the engine
|
||||
is so customizable.
|
||||
* and many more.
|
||||
The typical way to use Smarty 3 should also look familiar:
|
||||
|
||||
COPYRIGHT:
|
||||
Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
|
||||
This software is released under the GNU Lesser General Public License.
|
||||
Please read the disclaimer at the top of the Smarty.class.php file.
|
||||
require('Smarty.class.php');
|
||||
$smarty = new Smarty;
|
||||
$smarty->assign('foo','bar');
|
||||
$smarty->display('index.tpl');
|
||||
|
||||
|
||||
However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
|
||||
backward compatible with Smarty 2, except for the following items:
|
||||
|
||||
*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
|
||||
*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
|
||||
but still work. You will want to update your calls to Smarty 3 for maximum
|
||||
efficiency.
|
||||
|
||||
|
||||
There are many things that are new to Smarty 3. Here are the notable items:
|
||||
|
||||
LEXER/PARSER
|
||||
============
|
||||
|
||||
Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
|
||||
means Smarty has some syntax additions that make life easier such as in-template
|
||||
math, shorter/intuitive function parameter options, infinite function recursion,
|
||||
more accurate error handling, etc.
|
||||
|
||||
|
||||
WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
|
||||
=====================================
|
||||
|
||||
Smarty 3 allows expressions almost anywhere. Expressions can include PHP
|
||||
functions as long as they are not disabled by the security policy, object
|
||||
methods and properties, etc. The {math} plugin is no longer necessary but
|
||||
is still supported for BC.
|
||||
|
||||
Examples:
|
||||
{$x+$y} will output the sum of x and y.
|
||||
{$foo = strlen($bar)} function in assignment
|
||||
{assign var=foo value= $x+$y} in attributes
|
||||
{$foo = myfunct( ($x+$y)*3 )} as function parameter
|
||||
{$foo[$x+3]} as array index
|
||||
|
||||
Smarty tags can be used as values within other tags.
|
||||
Example: {$foo={counter}+3}
|
||||
|
||||
Smarty tags can also be used inside double quoted strings.
|
||||
Example: {$foo="this is message {counter}"}
|
||||
|
||||
You can define arrays within templates.
|
||||
Examples:
|
||||
{assign var=foo value=[1,2,3]}
|
||||
{assign var=foo value=['y'=>'yellow','b'=>'blue']}
|
||||
Arrays can be nested.
|
||||
{assign var=foo value=[1,[9,8],3]}
|
||||
|
||||
There is a new short syntax supported for assigning variables.
|
||||
Example: {$foo=$bar+2}
|
||||
|
||||
You can assign a value to a specific array element. If the variable exists but
|
||||
is not an array, it is converted to an array before the new values are assigned.
|
||||
Examples:
|
||||
{$foo['bar']=1}
|
||||
{$foo['bar']['blar']=1}
|
||||
|
||||
You can append values to an array. If the variable exists but is not an array,
|
||||
it is converted to an array before the new values are assigned.
|
||||
Example: {$foo[]=1}
|
||||
|
||||
You can use a PHP-like syntax for accessing array elements, as well as the
|
||||
original "dot" notation.
|
||||
Examples:
|
||||
{$foo[1]} normal access
|
||||
{$foo['bar']}
|
||||
{$foo['bar'][1]}
|
||||
{$foo[$x+$x]} index may contain any expression
|
||||
{$foo[$bar[1]]} nested index
|
||||
{$foo[section_name]} smarty section access, not array access!
|
||||
|
||||
The original "dot" notation stays, and with improvements.
|
||||
Examples:
|
||||
{$foo.a.b.c} => $foo['a']['b']['c']
|
||||
{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index
|
||||
{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index
|
||||
{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index
|
||||
|
||||
note that { and } are used to address ambiguties when nesting the dot syntax.
|
||||
|
||||
Variable names themselves can be variable and contain expressions.
|
||||
Examples:
|
||||
$foo normal variable
|
||||
$foo_{$bar} variable name containing other variable
|
||||
$foo_{$x+$y} variable name containing expressions
|
||||
$foo_{$bar}_buh_{$blar} variable name with multiple segments
|
||||
{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1.
|
||||
|
||||
Object method chaining is implemented.
|
||||
Example: {$object->method1($x)->method2($y)}
|
||||
|
||||
{for} tag added for looping (replacement for {section} tag):
|
||||
{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for}
|
||||
Any number of statements can be used separated by comma as the first
|
||||
inital expression at {for}.
|
||||
|
||||
{for $x = $start to $end step $step} ... {/for}is in the SVN now .
|
||||
You can use also
|
||||
{for $x = $start to $end} ... {/for}
|
||||
In this case the step value will be automaticall 1 or -1 depending on the start and end values.
|
||||
Instead of $start and $end you can use any valid expression.
|
||||
Inside the loop the following special vars can be accessed:
|
||||
$x@iteration = number of iteration
|
||||
$x@total = total number of iterations
|
||||
$x@first = true on first iteration
|
||||
$x@last = true on last iteration
|
||||
|
||||
|
||||
The Smarty 2 {section} syntax is still supported.
|
||||
|
||||
New shorter {foreach} syntax to loop over an array.
|
||||
Example: {foreach $myarray as $var}...{/foreach}
|
||||
|
||||
Within the foreach loop, properties are access via:
|
||||
|
||||
$var@key foreach $var array key
|
||||
$var@iteration foreach current iteration count (1,2,3...)
|
||||
$var@index foreach current index count (0,1,2...)
|
||||
$var@total foreach $var array total
|
||||
$var@first true on first iteration
|
||||
$var@last true on last iteration
|
||||
|
||||
The Smarty 2 {foreach} tag syntax is still supported.
|
||||
|
||||
NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
|
||||
If you want to access an array element with index foo, you must use quotes
|
||||
such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
|
||||
|
||||
while block tag is now implemented:
|
||||
{while $foo}...{/while}
|
||||
{while $x lt 10}...{/while}
|
||||
|
||||
Direct access to PHP functions:
|
||||
Just as you can use PHP functions as modifiers directly, you can now access
|
||||
PHP functions directly, provided they are permitted by security settings:
|
||||
{time()}
|
||||
|
||||
There is a new {function}...{/function} block tag to implement a template function.
|
||||
This enables reuse of code sequences like a plugin function. It can call itself recursively.
|
||||
Template function must be called with the new {call name=foo...} tag.
|
||||
|
||||
Example:
|
||||
|
||||
Template file:
|
||||
{function name=menu level=0}
|
||||
<ul class="level{$level}">
|
||||
{foreach $data as $entry}
|
||||
{if is_array($entry)}
|
||||
<li>{$entry@key}</li>
|
||||
{call name=menu data=$entry level=$level+1}
|
||||
{else}
|
||||
<li>{$entry}</li>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</ul>
|
||||
{/function}
|
||||
|
||||
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
|
||||
['item3-3-1','item3-3-2']],'item4']}
|
||||
|
||||
{call name=menu data=$menu}
|
||||
|
||||
|
||||
Generated output:
|
||||
* item1
|
||||
* item2
|
||||
* item3
|
||||
o item3-1
|
||||
o item3-2
|
||||
o item3-3
|
||||
+ item3-3-1
|
||||
+ item3-3-2
|
||||
* item4
|
||||
|
||||
The function tag itself must have the "name" attribute. This name is the tag
|
||||
name when calling the function. The function tag may have any number of
|
||||
additional attributes. These will be default settings for local variables.
|
||||
|
||||
New {nocache} block function:
|
||||
{nocache}...{/nocache} will declare a section of the template to be non-cached
|
||||
when template caching is enabled.
|
||||
|
||||
New nocache attribute:
|
||||
You can declare variable/function output as non-cached with the nocache attribute.
|
||||
Examples:
|
||||
|
||||
{$foo nocache=true}
|
||||
{$foo nocache} /* same */
|
||||
|
||||
{foo bar="baz" nocache=true}
|
||||
{foo bar="baz" nocache} /* same */
|
||||
|
||||
{time() nocache=true}
|
||||
{time() nocache} /* same */
|
||||
|
||||
Or you can also assign the variable in your script as nocache:
|
||||
$smarty->assign('foo',$something,true); // third param is nocache setting
|
||||
{$foo} /* non-cached */
|
||||
|
||||
$smarty.current_dir returns the directory name of the current template.
|
||||
|
||||
You can use strings directly as templates with the "string" resource type.
|
||||
Examples:
|
||||
$smarty->display('string:This is my template, {$foo}!'); // php
|
||||
{include file="string:This is my template, {$foo}!"} // template
|
||||
|
||||
|
||||
|
||||
VARIABLE SCOPE / VARIABLE STORAGE
|
||||
=================================
|
||||
|
||||
In Smarty 2, all assigned variables were stored within the Smarty object.
|
||||
Therefore, all variables assigned in PHP were accessible by all subsequent
|
||||
fetch and display template calls.
|
||||
|
||||
In Smarty 3, we have the choice to assign variables to the main Smarty object,
|
||||
to user-created data objects, and to user-created template objects.
|
||||
These objects can be chained. The object at the end of a chain can access all
|
||||
variables belonging to that template and all variables within the parent objects.
|
||||
The Smarty object can only be the root of a chain, but a chain can be isolated
|
||||
from the Smarty object.
|
||||
|
||||
All known Smarty assignment interfaces will work on the data and template objects.
|
||||
|
||||
Besides the above mentioned objects, there is also a special storage area for
|
||||
global variables.
|
||||
|
||||
A Smarty data object can be created as follows:
|
||||
$data = $smarty->createData(); // create root data object
|
||||
$data->assign('foo','bar'); // assign variables as usual
|
||||
$data->config_load('my.conf'); // load config file
|
||||
|
||||
$data= $smarty->createData($smarty); // create data object having a parent link to
|
||||
the Smarty object
|
||||
|
||||
$data2= $smarty->createData($data); // create data object having a parent link to
|
||||
the $data data object
|
||||
|
||||
A template object can be created by using the createTemplate method. It has the
|
||||
same parameter assignments as the fetch() or display() method.
|
||||
Function definition:
|
||||
function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
|
||||
The first parameter can be a template name, a smarty object or a data object.
|
||||
|
||||
Examples:
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
|
||||
$tpl->assign('foo','bar'); // directly assign variables
|
||||
$tpl->config_load('my.conf'); // load config file
|
||||
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object
|
||||
|
||||
The standard fetch() and display() methods will implicitly create a template object.
|
||||
If the $parent parameter is not specified in these method calls, the template object
|
||||
is will link back to the Smarty object as it's parent.
|
||||
|
||||
If a template is called by an {include...} tag from another template, the
|
||||
subtemplate links back to the calling template as it's parent.
|
||||
|
||||
All variables assigned locally or from a parent template are accessible. If the
|
||||
template creates or modifies a variable by using the {assign var=foo...} or
|
||||
{$foo=...} tags, these new values are only known locally (local scope). When the
|
||||
template exits, none of the new variables or modifications can be seen in the
|
||||
parent template(s). This is same behavior as in Smarty 2.
|
||||
|
||||
With Smarty 3, we can assign variables with a scope attribute which allows the
|
||||
availablility of these new variables or modifications globally (ie in the parent
|
||||
templates.)
|
||||
|
||||
Possible scopes are local, parent, root and global.
|
||||
Examples:
|
||||
{assign var=foo value='bar'} // no scope is specified, the default 'local'
|
||||
{$foo='bar'} // same, local scope
|
||||
{assign var=foo value='bar' scope='local'} // same, local scope
|
||||
|
||||
{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
|
||||
{$foo='bar' scope='parent'} // (normally the calling template)
|
||||
|
||||
{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can
|
||||
{$foo='bar' scope='root'} // be seen from all templates using the same root.
|
||||
|
||||
{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
|
||||
{$foo='bar' scope='global'} // they are available to any and all templates.
|
||||
|
||||
|
||||
The scope attribute can also be attached to the {include...} tag. In this case,
|
||||
the specified scope will be the default scope for all assignments within the
|
||||
included template.
|
||||
|
||||
|
||||
PLUGINS
|
||||
=======
|
||||
|
||||
Smarty3 are following the same coding rules as in Smarty2.
|
||||
The only difference is that the template object is passed as additional third parameter.
|
||||
|
||||
smarty_plugintype_name (array $params, object $smarty, object $template)
|
||||
|
||||
The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty2 internals.
|
||||
|
||||
|
||||
TEMPLATE INHERITANCE:
|
||||
=====================
|
||||
|
||||
With template inheritance you can define blocks, which are areas that can be
|
||||
overriden by child templates, so your templates could look like this:
|
||||
|
||||
parent.tpl:
|
||||
<html>
|
||||
<head>
|
||||
<title>{block name='title'}My site name{/block}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{block name='page-title'}Default page title{/block}</h1>
|
||||
<div id="content">
|
||||
{block name='content'}
|
||||
Default content
|
||||
{/block}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
child.tpl:
|
||||
{extends file='parent.tpl'}
|
||||
{block name='title'}
|
||||
Child title
|
||||
{/block}
|
||||
|
||||
grandchild.tpl:
|
||||
{extends file='child.tpl'}
|
||||
{block name='title'}Home - {$smarty.block.parent}{/block}
|
||||
{block name='page-title'}My home{/block}
|
||||
{block name='content'}
|
||||
{foreach $images as $img}
|
||||
<img src="{$img.url}" alt="{$img.description}" />
|
||||
{/foreach}
|
||||
{/block}
|
||||
|
||||
We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
|
||||
which tells Smarty to insert the default content from the parent template in its place.
|
||||
The content block was overriden to display the image files, and page-title has also be
|
||||
overriden to display a completely different title.
|
||||
|
||||
If we render grandchild.tpl we will get this:
|
||||
<html>
|
||||
<head>
|
||||
<title>Home - Child title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My home</h1>
|
||||
<div id="content">
|
||||
<img src="/example.jpg" alt="image" />
|
||||
<img src="/example2.jpg" alt="image" />
|
||||
<img src="/example3.jpg" alt="image" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
NOTE: In the child templates everything outside the {extends} or {block} tag sections
|
||||
is ignored.
|
||||
|
||||
The inheritance tree can be as big as you want (meaning you can extend a file that
|
||||
extends another one that extends another one and so on..), but be aware that all files
|
||||
have to be checked for modifications at runtime so the more inheritance the more overhead you add.
|
||||
|
||||
Instead of defining the parent/child relationships with the {extends} tag in the child template you
|
||||
can use the resource as follow:
|
||||
|
||||
$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
|
||||
|
||||
Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
|
||||
is appended or prepended to the child block content.
|
||||
|
||||
{block name='title' append} My title {/block}
|
||||
|
||||
|
||||
PHP STREAMS:
|
||||
============
|
||||
|
||||
(see online documentation)
|
||||
|
||||
VARIBLE FILTERS:
|
||||
================
|
||||
|
||||
(see online documentation)
|
||||
|
||||
|
||||
STATIC CLASS ACCESS AND NAMESPACE SUPPORT
|
||||
=========================================
|
||||
|
||||
You can register a class with optional namespace for the use in the template like:
|
||||
|
||||
$smarty->register->templateClass('foo','name\name2\myclass');
|
||||
|
||||
In the template you can use it like this:
|
||||
{foo::method()} etc.
|
||||
|
||||
|
||||
=======================
|
||||
|
||||
Please look through it and send any questions/suggestions/etc to the forums.
|
||||
|
||||
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
|
||||
|
||||
Monte and Uwe
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#Smarty 3 template engine
|
||||
##Distribution repository
|
||||
|
||||
*Read the NEW_FEATURES file for recent extensions to Smarty 3.1 functionality*
|
||||
|
||||
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
|
||||
|
||||
|
||||
The "smarty/smarty" package will start at libs/.... subfolder.
|
||||
|
||||
To get the latest stable version of Smarty 3.1 use
|
||||
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1"
|
||||
}
|
||||
|
||||
in your composer.json file.
|
||||
|
||||
To get the trunk version use
|
||||
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1@dev"
|
||||
}
|
||||
|
||||
For a specific version use something like
|
||||
|
||||
"require": {
|
||||
"smarty/smarty": "3.1.19"
|
||||
}
|
||||
|
||||
PHPUnit test can be installed by corresponding composer entries like
|
||||
|
||||
"require": {
|
||||
"smarty/smarty-phpunit": "3.1.19"
|
||||
}
|
||||
|
||||
Similar applies for the lexer/parser generator
|
||||
|
||||
"require": {
|
||||
"smarty/smarty-lexer": "3.1.19"
|
||||
}
|
||||
|
||||
Or you could use
|
||||
|
||||
"require": {
|
||||
"smarty/smarty-dev": "3.1.19"
|
||||
}
|
||||
|
||||
Which is a wrapper to install all 3 packages
|
||||
|
||||
|
||||
Composer can also be used for Smarty2 versions 2.6.24 to 2.6.28
|
||||
@@ -0,0 +1,124 @@
|
||||
// enable properties with removing #cache#
|
||||
#cache# $this->setCacheDir($serendipity['serendipityPath'] . 'cache');
|
||||
|
||||
#cache# $this->caching = true; // $this->setCaching(true);
|
||||
/*
|
||||
Caching is disabled, as long as we haven't figured out on how to use it best here....
|
||||
|
||||
Note: rodneyrehm
|
||||
A cache_id is (ideally) supposed to identify a single page.
|
||||
md5(REQUEST_URI) may _seem_ to be doing that, but /foo.html and /foo.html?foo=bar are the same resource
|
||||
from S9Y's point of view - with DIFFERENT REQUEST_URIs. Your approach leads to a number of problems:
|
||||
* flooding the cache space with duplicate content
|
||||
* essentially making clearCache() useless, as md5 checksums of /foo.html and /foo.html?foo=bar have
|
||||
exactly nothing in common.
|
||||
You want to specify the pieces of cachable content yourself. Go with a structure like
|
||||
post-123
|
||||
post-123|comments (if you have a page for all comments belonging to that post)
|
||||
post-123|comments|feed (if you have a comment feed for a certain post)
|
||||
now you can clearCache('post-123') and comments and comments|feed are killed as well.
|
||||
*/
|
||||
|
||||
/*
|
||||
// APC and MEMCACHE are loaded from this libs plugins folder,
|
||||
// but you need to have enabled caching by $smarty->caching = true (see Rodneys upper template structure note),
|
||||
// which makes clear why we can't use Smarty caching currently with S9y
|
||||
|
||||
// enable for APC in-memory (RAM) storage caching - must be enabled in PHP
|
||||
if(APC_EXTENSION_LOADED && !$serendipity['disable_apc']) {
|
||||
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
|
||||
$this->caching_type = 'apc'; //$this->setCachingType ( 'apc' );
|
||||
}
|
||||
// enable for MEMCACHE storage caching - must be enabled in PHP
|
||||
if(MEMCACHE_EXTENSION_LOADED && !$serendipity['disable_memcache']) {
|
||||
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
|
||||
$this->caching_type = 'memcache'; //$this->setCachingType ( 'memcache' );
|
||||
}
|
||||
*/
|
||||
|
||||
// does set cache also need to be set to true?
|
||||
#cache# $this->cache_modified_check = true; // to be used with display() method only, must be true to enable 304 headers
|
||||
|
||||
/*
|
||||
Note: rodneyrehm
|
||||
$cache_modified_check only works if you're using display() - it won't do anything on fetch().
|
||||
It won't do anything if you have non-caching plugins or {insert} tags, either.
|
||||
|
||||
We're working on making this more intelligent for 3.2, but? work with what you've got in 3.1 first.
|
||||
*/
|
||||
|
||||
// some documentary from the smarty forum
|
||||
/*
|
||||
With Smarty::CACHING_LIFETIME_SAVED the expiration date is written into the cached file.
|
||||
So each cache_id / compile_id combination may have their own cache lifetime.
|
||||
The point is simply, that once the cache lifetime (expiration date) has been saved to the cache file,
|
||||
it cannot be altered except for clearing and regenerating said cache file
|
||||
|
||||
Template Inheritance
|
||||
Using is_cached() on sub-templates has to set up caching before is_cached() calls,
|
||||
e.g if (!$smarty->isCached('sub_test.tpl')) { $smarty->assign('foo', $foo); }.
|
||||
The subtemplate will always be cached as specified in the {include} tag.
|
||||
Otherwise you could never cache a subtemplate with caching disabled for the main template.
|
||||
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
|
||||
So the example will cache sub_test.tpl, but not test.tpl
|
||||
Using is_cached() on subtemplates has to set up caching before is_cached() calls.
|
||||
The subtemplate will always be cached as specified in the {include} tag.
|
||||
Otherwise you could never cache a subtemplate with caching disabled for the main template.
|
||||
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
|
||||
So the example will cache sub_test.tpl but not test.tpl
|
||||
Use $smarty->caching = Smarty::CACHING_LIFETIME_SAVED; with {include file="sub_test.tpl" cache_lifetime="120"} in test.tpl;
|
||||
Use $smarty->caching = Smarty::CACHING_LIFETIME_CURRENT; with {include .... caching}
|
||||
*/
|
||||
|
||||
#cache# $this->caching = Smarty::CACHING_LIFETIME_CURRENT; // $this->setCaching(2); // 1 will change the end of lifetime immediately.
|
||||
# $this->caching = Smarty::CACHING_LIFETIME_SAVED; // $this->setCaching(Smarty::CACHING_LIFETIME_SAVED);
|
||||
# $this->caching = Smarty::CACHING_OFF; // $this->setCaching(Smarty::CACHING_OFF) // stop caching >= 3.1.4
|
||||
|
||||
/*
|
||||
Note: rodneyrehm
|
||||
The CACHING_LIFETIME_SAVED option is something you only really "need" if many cache files have different lifetimes.
|
||||
I've used Smarty intensively over the past years and I _never_ required LIFETIME_SAVED...
|
||||
|
||||
you can do $force_cache = true; to make the current page re-render to cache. This actually allows you to work with a very high
|
||||
cache_lifetime and poll a secondary modified time from somewhere. You could then implement the serve-stale-until-updated caching approach.
|
||||
I'll blog about this? probably around christmas
|
||||
*/
|
||||
|
||||
// set the cache_lifetime for index.tpl to 5 minutes
|
||||
#cache# $this->cache_lifetime = 300; // $this->setCacheLifetime(300); // 86400; // one day: 60*60*24
|
||||
|
||||
// some documentary from the smarty forum
|
||||
/*
|
||||
Smarty caching is based purely on the fetch() or display() call. So:
|
||||
$smarty->fetch('application.tpl');
|
||||
Will generate a cached output and use that on repeated calls. If you have multiple versions of this call, you need to pass a cache_id. Example:
|
||||
$cache_id = md5($_SERVER['REQUEST_URI']);
|
||||
$smarty->fetch('application.tpl',$cache_id);
|
||||
It is entirely up to you what is taken into account for the cache_id (URL, etc.)
|
||||
*/
|
||||
|
||||
// does this mean $this->setCacheId($id); is useless here and has to be set where the actual templates are called? or does ist work as something default?
|
||||
/*
|
||||
Note: rodneyrehm
|
||||
when fetch(tpl) is called, Smarty::$cache_id is injected. If you need a single cache_id for the whole render complex, this may be the sane thing to do.
|
||||
But you'll probably segment certain content. A Post does not have to be reendered for every new comment. It thus makes sense to separate these entities
|
||||
into their own cache spaces. In turn they'd probably receive their own cache_ids. Although that is not _necessary_ as template_name and cache_id work in
|
||||
conjunction. If both are supplied (to say clearCache()) template_name increases the specificity of cache_id, so only those items are purged that meet
|
||||
both criteria.
|
||||
*/
|
||||
|
||||
// some documentary from the smarty forum
|
||||
/*
|
||||
Smarty will use the cache_id for distributing the cache files into sub_dirs
|
||||
A cache id is used if you cache different output generated by the same template as for example on a product page.
|
||||
In such a case you should use a product id as cache id.
|
||||
$this->cache_id($id); // $this->setCacheId($id);
|
||||
*/
|
||||
|
||||
#cache# $this->cache_id = md5($_SERVER['REQUEST_URI']); // this isn't a good idea either, better have it disabled or use a special id
|
||||
/*
|
||||
Note: Ian
|
||||
What kind of Serendipity ID could this be?
|
||||
- see Rodneys first caching note
|
||||
*/
|
||||
|
||||
@@ -1,428 +0,0 @@
|
||||
2.6.7
|
||||
-----
|
||||
|
||||
Those using Smarty with security enabled: a hole was found that allowed PHP code to be executed from within a template file. This has been fixed and you are engouraged to upgrade immediately. Note that this hole does NOT affect the security of your web server or PHP applications, only the ability for someone editing a template to execute PHP code. Other changes in this release can be found in the NEWS file.
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
Very minor adjustments since RC2, see the NEWS file for details.
|
||||
|
||||
2.5.0-RC2
|
||||
---------
|
||||
|
||||
Many fixes since the RC1 release. This one is as close to production quality as
|
||||
they come, so this will be the last release before 2.5.0. The SGML documentation
|
||||
files have also been removed from the tarball. If you want them, get them from
|
||||
the CVS repository.
|
||||
|
||||
2.5.0-RC1
|
||||
---------
|
||||
|
||||
Release Candidate 1. All $smarty vars can now be dynamic, such as
|
||||
$smarty.get.$foo. A new class function get_function_object() gets you a
|
||||
reference to an assigned object, useful within your own custom functions.
|
||||
append() can now merge as well as append with a third optional attribute. A new
|
||||
class function get_config_vars() was added, and get_template_vars() can now be
|
||||
used to get individual vars. Full variable syntax is now supported within
|
||||
double quotes via a backtick (`) syntax. Files created by smarty are now
|
||||
written to a tmp file then renamed to avoid file lock retention. html_radios,
|
||||
html_checkboxes, html_table, html_image, nl2br functions added, see the NEWS
|
||||
file for full details.
|
||||
|
||||
2.4.2
|
||||
-----
|
||||
Another point release. Added support for dynamic object reference syntax
|
||||
($foo->$bar), support for full variable syntax within quotes ("$foo[0].bar"),
|
||||
and other minor fixes. See the NEWS file for full details.
|
||||
|
||||
2.4.1
|
||||
-----
|
||||
|
||||
This is basically a point release, cleaning up a few things caught
|
||||
in the 2.4.0 release. See the NEWS file for full details.
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
Smarty now supports the ability to access objects within the templates. Two
|
||||
methods are available, one which closely follows Smartys conventions, and
|
||||
another that follows more traditional object syntax for those familiar with
|
||||
PHP.
|
||||
|
||||
The internal compiling engine has also undergone some major work. The regex
|
||||
parsing was rewritten to be much more strict, more secure and more
|
||||
maintainable. Config files are now compiled, which can speed up pages quite a
|
||||
bit that use config files extensively. Assigned variables are no longer
|
||||
extracted to PHP namespace, saving an extract call for every template. There is
|
||||
now support for applying modifiers to static values and functions. You can now
|
||||
access constants with $smarty.const.VAR. See the NEWS file for complete
|
||||
changes.
|
||||
|
||||
2.3.1
|
||||
-----
|
||||
|
||||
The mtime on compiled files will now match the source files, in the case where
|
||||
the source file may not get the current timestamp, recompiling will still work
|
||||
as expected. Proper support for open_basedir has been added, so Smarty should
|
||||
work correctly in safe mode. Added a few new features such as textformat block
|
||||
function, strip variable modifier and optgroup support for html_options. Also
|
||||
other minor bug fixes, see the Change Log.
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
Smarty now has a {debug} template function that brings up the debugging console
|
||||
right where {debug} is called, regardless of $debugging settings. This works a
|
||||
little different than turning on $debugging in the sense that it shows all the
|
||||
template variables available at the time {debug} is called, including local
|
||||
scope vars. It does not show the templates names however, since this
|
||||
executed during runtime of the template.
|
||||
|
||||
You can now supply an expire time when clearing cache or compile files. This is
|
||||
mostly useful for removing stale files via the API.
|
||||
|
||||
Plugins now stop execution upon error, instead of outputting a warning and
|
||||
continuing.
|
||||
|
||||
Two new API functions, assign_by_ref() and append_by_ref() were added. They
|
||||
allow assigning template variables by reference. This can make a significant
|
||||
performance gain, especially if you are assigning large arrays of data. PHP 5.0
|
||||
will do this implicitly, so these functions are basically workarounds.
|
||||
|
||||
Several misc bug fixes, see the Change Log for information.
|
||||
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
Smarty now allows an array of paths for the $plugin_dir class variable. The
|
||||
directories will be searched in the order they are given, so for efficiency keep
|
||||
the most-used plugins at the top. Also, absolute paths to the plugin directories are
|
||||
more efficient than relying on the PHP include_path.
|
||||
|
||||
Cache files can now be grouped with the cache_id. See the documentation under
|
||||
the new "Caching" section for details. compile_id also respects the same
|
||||
grouping syntax. The cache/compile file structure changed, so be sure to clear
|
||||
out all your cache and compile files when upgrading Smarty. Also if you are
|
||||
using PHP-accelerator, restart apache. I've seen some quirky things happen if
|
||||
the phpa files do not get cleared (known issue with phpa and parent
|
||||
class-member changes, so just clear 'em.)
|
||||
|
||||
Smarty now correctly respects the PHP include_path for $template_dir, $compile_dir,
|
||||
$cache_dir, $config_dir and $plugin_dir. Be aware that relying on the
|
||||
include_path is an overhead, try to use absolute pathnames when possible
|
||||
(or relative to working directory.)
|
||||
|
||||
Documentation has been updated and rearranged a bit. Most notably, the
|
||||
installation instructions are completely revamped, and a new Caching section
|
||||
explains Smarty's caching in detail along with the new grouping functionality.
|
||||
|
||||
Many misc. bug fixes and enhancements, see the full ChangeLog (NEWS file) for
|
||||
details.
|
||||
|
||||
2.1.1
|
||||
-----
|
||||
|
||||
There was a bug with template paths and the include_path, this has been fixed.
|
||||
Also register_outputfilter() did not work, this is fixed. A new template
|
||||
function named "cycle" has been added to the distribution, nice for cycling
|
||||
through a list (or array) of values.
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
This release has quite a few new features and fixes. Most notable are the
|
||||
introduction of block functions, so you can write plugins that work on a block
|
||||
of text with {func}{/func} notation. Also output filters were added, so you can
|
||||
apply a function against the output of your templates. This differs from the
|
||||
postfilter function, which works on the compiled template at compile time, and
|
||||
output filters work on the template output at runtime.
|
||||
|
||||
Many other features and bug fixes are noted in the NEWS file.
|
||||
|
||||
|
||||
2.0.1
|
||||
-----
|
||||
|
||||
This is a point release, fixing a few bugs and cleaning things up. A plugin
|
||||
was renamed, the dash "-" was removed from compiled template and cached file
|
||||
names. If you're upgrading, you might want to clear them out first. See the
|
||||
ChangeLog for details.
|
||||
|
||||
2.0.0
|
||||
-----
|
||||
|
||||
This release is a huge milestone for Smarty. Most notable new things are a
|
||||
plugin architecture, removal of PEAR dependency, and optimizations that
|
||||
drastically improve the performance of Smarty in most cases.
|
||||
|
||||
The plugin architecture allows modifiers, custom functions, compiler functions,
|
||||
prefilters, postfilters, resources, and insert functions to be added by
|
||||
simply dropping a file into the plugins directory. Once dropped in, they are
|
||||
automatically registered by the template engine. This makes user-contributed
|
||||
plugins easy to manage, as well as the internal workings of Smarty easy to
|
||||
control and customize. This new architecture depends on the __FILE__ constant,
|
||||
which contains the full path to the executing script. Some older versions of
|
||||
PHP incorrectly gave the script name and not the full filesystem path. Be sure
|
||||
your version of PHP populates __FILE__ correctly. If you use custom template
|
||||
resource functions, the format of these changed with the plugin architecture.
|
||||
Be sure to update your functions accordingly. See the template resource section
|
||||
of the documentation.
|
||||
|
||||
The PEAR dependancy was removed from Smarty. The Config_File class that comes
|
||||
with Smarty was actually what needed PEAR for error handling which Smarty didn't
|
||||
use, but now everything is self-contained.
|
||||
|
||||
Performance improvements are graphed on the benchmark page, you will see that
|
||||
overall performance has been sped up by as much as 80% in some cases.
|
||||
|
||||
Smarty-cached pages now support If-Modified-Since headers, meaning that if a
|
||||
cached template page has not changed since the last request, a "304 Not
|
||||
Modified" header will be sent instead of resending the same page. This is
|
||||
disabled by default, change the setting of $cache_modified_check.
|
||||
|
||||
|
||||
1.5.2
|
||||
-----
|
||||
|
||||
Mostly bug fixes, added a default template resource handler.
|
||||
|
||||
|
||||
1.5.1
|
||||
-----
|
||||
|
||||
Critical bug fix release. If you use caching, you'll need to upgrade.
|
||||
|
||||
|
||||
1.5.0
|
||||
-----
|
||||
|
||||
Several feature enhancements were made to this version, most notably the
|
||||
{foreach ...} command which is an alternative to {section ...} with an easier
|
||||
syntax for looping through a single array of values. Several functions were
|
||||
enhanced so that the output can be automatically assigned to a template
|
||||
variable instead of displayed (assign attribute). Cache files can now be
|
||||
controlled with a custom function as an alternative to the built-in file based
|
||||
method. Many code cleanups and bug fixed went into this release as well.
|
||||
|
||||
|
||||
1.4.6
|
||||
-----
|
||||
|
||||
The behavior with caching and compile_check has been slightly enhanced. If
|
||||
caching is enabled AND compile_check is enabled, the cache will immediately get
|
||||
regenerated if _any_ involved template or config file is updated. This imposes
|
||||
a slight performance hit because it must check all the files for changes, so be
|
||||
sure to run live sites with caching enabled and compile_check disabled for best
|
||||
performance. If you update a template or config file, simply turn on
|
||||
compile_check, load the page, then turn it back off. This will update the cache
|
||||
file with the new content. This is accomplished by maintaining a list of
|
||||
included/loaded templates and config files at the beginning of the cache file.
|
||||
Therefore it is advisable to remove all cache files after upgrading to 1.4.6
|
||||
(although not absolutely necessary, old cache files will regenerate)
|
||||
|
||||
The debug console now has script timing and array values printed. You MUST
|
||||
update your debug.tpl file with this version of Smarty. Also, the new debug.tpl
|
||||
will not work with older versions of Smarty.
|
||||
|
||||
|
||||
1.4.5
|
||||
-----
|
||||
|
||||
Mostly bug fixes and minor improvements. Added compile id for separate compiled
|
||||
versions of the same script. The directory format and filename convention for
|
||||
the files in templates_c has changed, so you may want to remove all of the
|
||||
existing ones before you upgrade.
|
||||
|
||||
|
||||
1.4.4
|
||||
-----
|
||||
|
||||
A few bug fixes, new section looping attributes and properties, debugging
|
||||
console function for control via URL, and overLib integration and access
|
||||
to request variables from within the template.
|
||||
|
||||
|
||||
1.4.3
|
||||
-----
|
||||
|
||||
This release has a few bug fixes and several enhancements. Smarty now supports
|
||||
template security for third-party template editing. These features disallow the
|
||||
ability for someone to execute commands or PHP code from the template language.
|
||||
Smarty also now has a built-in debugging console, which is a javascript pop-up
|
||||
window that displays all the included template names and assigned variables.
|
||||
|
||||
|
||||
1.4.2
|
||||
-----
|
||||
|
||||
This was mostly one bug fix with variable scoping within included templates
|
||||
and a few documentation changes and updates. See the ChangeLog file for full
|
||||
details.
|
||||
|
||||
|
||||
1.4.1
|
||||
-----
|
||||
|
||||
It seems that the EX_LOCK logic from the previous release didn't fix all the
|
||||
problems with windows platforms. Hopefully this one does. It basically
|
||||
disables file locking on windows, so there is a potential that two programs
|
||||
could write over the same file at the same time, fyi.
|
||||
|
||||
The reset is minor bug fixes, please refer to the ChangeLog file.
|
||||
|
||||
|
||||
1.4.0
|
||||
-----
|
||||
|
||||
IMPORTANT NOTICE
|
||||
|
||||
Smarty now has a new syntax for accessing elements within section loops. The
|
||||
new syntax is easier to use and nicely handles data structures of any
|
||||
complexity. Consequently, this breaks the old syntax.
|
||||
|
||||
Here is an example of the syntax change:
|
||||
|
||||
old syntax:
|
||||
{$sec1/sec2/sec3/customer.phone}
|
||||
|
||||
new syntax:
|
||||
{$customer[$sec1][$sec2][$sec3].phone}
|
||||
|
||||
The section names used to come first, followed by the variable name. Now the
|
||||
variable name always comes first, followed by the section names in brackets.
|
||||
You can access variable indexes anywhere, depending on how you passed the
|
||||
variables in.
|
||||
|
||||
To fix your current templates, we have provided a script that will adjust the
|
||||
syntax for you. Located in misc/fix_vars.php, run this script from the the
|
||||
command line, giving each template as an argument. Be sure to use absolute
|
||||
pathnames, or pathnames relative to the executing script. Probably the easiest
|
||||
way to do this is to copy the fix_vars.php script into your template directory
|
||||
and run 'php -q fix_vars.php *.tpl' Be sure you have proper write permission,
|
||||
and backup your scripts first to be safe! The examples in the 1.4.0
|
||||
documentation have been updated to reflect the changes.
|
||||
|
||||
cd /path/to/templates
|
||||
cp /path/to/fix_vars.php .
|
||||
find . -name "*.tpl" -exec php -q ./fix_vars.php {} \;
|
||||
|
||||
NEW AND IMPROVED COMPILATION PROCESS
|
||||
|
||||
Smarty 1.4.0 also has a new compilation process. Instead of compiling all the
|
||||
templates up front, it now compiles them at runtime. This has several
|
||||
advantages. First of all, there is no longer a need to have a single template
|
||||
directory. You can now have arbitrary template sources, such as multiple
|
||||
directories or even database calls. This also speeds the performance of Smarty
|
||||
when $compile_check is enabled, since it is only checking the template that is
|
||||
being executed instead of everything found in the template directory. The
|
||||
$tpl_file_ext is no longer needed, but kept for backward compatability.
|
||||
Templates can now be named anything you like with any extension.
|
||||
|
||||
MINOR FIXES
|
||||
|
||||
A workaround for LOCK_EX on Windows systems was added, and changed a couple of
|
||||
file permissions for better security on public servers.
|
||||
|
||||
$show_info_header is now defaulted to false instead of true. This header causes
|
||||
problems when displaying content other than HTML, so now you must explicitly
|
||||
set this flag to true to show the header information (or change the default in
|
||||
your copy of Smarty.)
|
||||
|
||||
Documentation is written in docbook format. I updated the docbook -> HTML
|
||||
generating software & style-sheets, and consequently the examples are no longer
|
||||
in a different background color. If anyone wants to contribute a better
|
||||
stylesheet or help with documentation, drop me a line. <monte at ohrt dot com>
|
||||
|
||||
CHANGES/ENHANCEMENTS/UPDATES
|
||||
|
||||
date_format, html_select_date and html_select_time used to require a unix
|
||||
timestamp as the format of the date passed into the template. Smarty is now a
|
||||
bit smarter at this. It will take a unix timestamp, a mysql timestamp, or any
|
||||
date string that is parsable by strtotime, such as 10/01/2001 or 2001-10-01,
|
||||
etc. Just give some formats a try and see what works.
|
||||
|
||||
Smarty now has template prefilters, meaning that you can run your templates
|
||||
through custom functions before they are compiled. This is good for things like
|
||||
removing unwanted comments, keeping an eye on words or functionality people are
|
||||
putting in templates, translating XML -> HTML, etc. See the register_prefilter
|
||||
documentation for more info.
|
||||
|
||||
Another addition are the so-called compiler functions. These are custom
|
||||
functions registered by the user that are executed at compilation time of the
|
||||
template. They can be used to inject PHP code or time-sensitive static content
|
||||
into the compiled template.
|
||||
|
||||
The run-time custom functions are now passed the Smarty object as the second
|
||||
parameter. This can be used, for example, to assign or clear template variables
|
||||
from inside the custom function.
|
||||
|
||||
clear_compile_dir() was added for clearing out compiled versions of your
|
||||
templates. Not something normally needed, but you may have a need for this if
|
||||
you have $compile_check set to false and you periodically update templates via
|
||||
some automated process. As of 1.4.0, uncompiled templates _always_ get
|
||||
compiled regardless of $compile_check setting, although they won't be checked
|
||||
for recompile if $compile_check is set to false.
|
||||
|
||||
You can now refer to properties of objects assigned from PHP by using the '->'
|
||||
symbol and specifying the property name after it, e.g. $foo->bar.
|
||||
|
||||
{php}{/php} tags were added to embed php into the templates. Not normally
|
||||
needed, but some circumstances may call for it. Check out the "componentized
|
||||
templates" tip in the documentation for an example.
|
||||
|
||||
{capture}{/capture} and {counter} functions were added. See the documentation
|
||||
for a complete description and examples.
|
||||
|
||||
UPGRADE NOTES
|
||||
|
||||
The format of the files created in the $compile_dir are now a bit different.
|
||||
The compiled template filename is the template resource name url-encoded.
|
||||
Therefore, all compiled files are now in the top directory of $compile_dir.
|
||||
This was done to make way for arbitrary template resources. Each compiled
|
||||
template also has a header that states what template resource was used to
|
||||
create it. From a unix command prompt, you can use "head -2 *" to see the first
|
||||
two lines of each file.
|
||||
|
||||
When upgrading to 1.4.0, you will want to clear out all your old files in the
|
||||
$compile_dir. If you have $compile_check set to false and the compiled template
|
||||
does not yet exist, it will compile it regardless of this setting. This way you
|
||||
can clear out the $compile_dir and not worry about setting $compile_check to
|
||||
true to get the inital compilation under way.
|
||||
|
||||
|
||||
1.3.2
|
||||
-----
|
||||
|
||||
Smarty now has (an optional) header prepended to the output of the Smarty
|
||||
templates. This displays the Smarty version and the date/time when the page was
|
||||
generated. This is useful for debugging your cache routines, and purely
|
||||
informational so there is evidence that the page was generated by Smarty. Set
|
||||
$show_info_header to false to disable it.
|
||||
|
||||
{config_load ...} performance was tuned by placing the loaded variables into a
|
||||
global array, so basically a config file is read from the file system and
|
||||
placed into a php array structure only once, no matter how many times it is
|
||||
called in any of the templates. The scope of the loaded variables has changed a
|
||||
bit as well. Variables loaded by config_load used to be treated as global
|
||||
variables, meaning that parent templates (templates that included the current
|
||||
template) could see them. Now the default behavior is such that loaded
|
||||
variables are only visible by the current template and child templates (all
|
||||
templates included after the {config_load ...} is called.) To mimic the
|
||||
original behavior, provide the attribute "global=yes" like so: {config_load
|
||||
file="mystuff.conf" global=yes}. Now when you load in mystuff.conf, the
|
||||
variables will be visible to parent templates (merged with any existing config
|
||||
variables.)
|
||||
|
||||
A formatting attribute was added to the {math ...} function, adding the ability
|
||||
to control the format of the output. Use the same formatting syntax as the PHP
|
||||
function sprintf().
|
||||
|
||||
{html_select_time ...} was added, a custom function that works much like
|
||||
{html_select_date ...} except it displays time elements instead of dates.
|
||||
|
||||
A few custom modifiers were added: count_characters, count_words,
|
||||
count_sentences, count_paragraphs. All pretty self-explanatory.
|
||||
|
||||
/* vim: set et: */
|
||||
@@ -0,0 +1,109 @@
|
||||
= Known incompatibilities with Smarty 2 =
|
||||
|
||||
== Syntax ==
|
||||
|
||||
Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported
|
||||
by a wrapper but deprecated. See the README that comes with Smarty 3 for more
|
||||
information.
|
||||
|
||||
The {$array|@mod} syntax has always been a bit confusing, where an "@" is required
|
||||
to apply a modifier to an array instead of the individual elements. Normally you
|
||||
always want the modifier to apply to the variable regardless of its type. In Smarty 3,
|
||||
{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the
|
||||
modifier will still apply to the array. If you really want the modifier to apply to
|
||||
each array element, you must loop the array in-template, or use a custom modifier that
|
||||
supports array iteration. Most smarty functions already escape values where necessary
|
||||
such as {html_options}
|
||||
|
||||
== PHP Version ==
|
||||
Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is disabled by default. The use of {php} tags is
|
||||
deprecated. It can be enabled with $smarty->allow_php_tag=true.
|
||||
|
||||
But if you scatter PHP code which belongs together into several
|
||||
{php} tags it may not work any longer.
|
||||
|
||||
== Delimiters and whitespace ==
|
||||
Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
|
||||
== Unquoted Strings ==
|
||||
Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings
|
||||
in parameters. Smarty3 is more restrictive. You can still pass strings without quotes
|
||||
so long as they contain no special characters. (anything outside of A-Za-z0-9_)
|
||||
|
||||
For example filename strings must be quoted
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl'}
|
||||
</source>
|
||||
|
||||
== Extending the Smarty class ==
|
||||
Smarty 3 makes use of the __construct method for initialization. If you are extending
|
||||
the Smarty class, its constructor is not called implicitly if the your child class defines
|
||||
its own constructor. In order to run Smarty's constructor, a call to parent::__construct()
|
||||
within your child constructor is required.
|
||||
|
||||
<source lang="php">
|
||||
class MySmarty extends Smarty {
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
// your initialization code goes here
|
||||
|
||||
}
|
||||
}
|
||||
</source>
|
||||
|
||||
== Autoloader ==
|
||||
Smarty 3 does register its own autoloader with spl_autoload_register. If your code has
|
||||
an existing __autoload function then this function must be explicitly registered on
|
||||
the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php
|
||||
for further details.
|
||||
|
||||
== Plugin Filenames ==
|
||||
Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames
|
||||
to be lower case. Because of this, Smarty plugin file names must also be lowercase.
|
||||
In Smarty 2, mixed case file names did work.
|
||||
|
||||
== Scope of Special Smarty Variables ==
|
||||
In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach...
|
||||
had global scope. If you had loops with the same name in subtemplates you could accidentally
|
||||
overwrite values of parent template.
|
||||
|
||||
In Smarty 3 these special Smarty variable have only local scope in the template which
|
||||
is defining the loop. If you need their value in a subtemplate you have to pass them
|
||||
as parameter.
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl' index=$smarty.section.foo.index}
|
||||
</source>
|
||||
|
||||
== SMARTY_RESOURCE_CHAR_SET ==
|
||||
Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset.
|
||||
This is now used also on modifiers like escape as default charset. If your templates use
|
||||
other charsets make sure that you define the constant accordingly. Otherwise you may not
|
||||
get any output.
|
||||
|
||||
== newline at {if} tags ==
|
||||
A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source.
|
||||
If one of the {if} tags is at the line end you will now get a newline in the HTML output.
|
||||
|
||||
== trigger_error() ==
|
||||
The API function trigger_error() has been removed because it did just map to PHP trigger_error.
|
||||
However it's still included in the Smarty2 API wrapper.
|
||||
|
||||
== Smarty constants ==
|
||||
The constants
|
||||
SMARTY_PHP_PASSTHRU
|
||||
SMARTY_PHP_QUOTE
|
||||
SMARTY_PHP_REMOVE
|
||||
SMARTY_PHP_ALLOW
|
||||
have been replaced with class constants
|
||||
Smarty::PHP_PASSTHRU
|
||||
Smarty::PHP_QUOTE
|
||||
Smarty::PHP_REMOVE
|
||||
Smarty::PHP_ALLOW
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
== Smarty2 backward compatibility ==
|
||||
All Smarty2 specific API functions and deprecated functionallity has been moved
|
||||
to the SmartyBC class.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== {include_php} Tag ==
|
||||
The {include_php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {include_php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== php template resource ==
|
||||
The support of the php template resource is removed.
|
||||
|
||||
== $cache_dir, $compile_dir, $config_dir, $template_dir access ==
|
||||
The mentioned properties can't be accessed directly any longer. You must use
|
||||
corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir()
|
||||
|
||||
== obsolete Smarty class properties ==
|
||||
The following no longer used properties are removed:
|
||||
$allow_php_tag
|
||||
$allow_php_template
|
||||
$deprecation_notices
|
||||
@@ -0,0 +1,306 @@
|
||||
Smarty 3.1 Notes
|
||||
================
|
||||
|
||||
Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all
|
||||
backward compatibility has been moved to a separate class file named
|
||||
SmartyBC.class.php. If you require compatibility with 2.0, you will
|
||||
need to use this class.
|
||||
|
||||
Some differences from 3.0 are also present. 3.1 begins the journey of
|
||||
requiring setters/getters for property access. So far this is only
|
||||
implemented on the five directory properties: template_dir,
|
||||
plugins_dir, configs_dir, compile_dir and cache_dir. These properties
|
||||
are now protected, it is required to use the setters/getters instead.
|
||||
That said, direct property access will still work, however slightly
|
||||
slower since they will now fall through __set() and __get() and in
|
||||
turn passed through the setter/getter methods. 3.2 will exhibit a full
|
||||
list of setter/getter methods for all (currently) public properties,
|
||||
so code-completion in your IDE will work as expected.
|
||||
|
||||
There is absolutely no PHP allowed in templates any more. All
|
||||
deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC
|
||||
class if you need any backward compatibility.
|
||||
|
||||
Internal Changes
|
||||
|
||||
Full UTF-8 Compatibility
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten to fully
|
||||
support UTF-8 strings if Multibyte String is available. Without
|
||||
MBString UTF-8 cannot be handled properly. For those rare cases where
|
||||
templates themselves have to juggle encodings, the new modifiers
|
||||
to_charset and from_charset may come in handy.
|
||||
|
||||
Plugin API and Performance
|
||||
|
||||
All Plugins (modifiers, functions, blocks, resources,
|
||||
default_template_handlers, etc) are now receiving the
|
||||
Smarty_Internal_Template instance, where they were supplied with the
|
||||
Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template
|
||||
mimics the behavior of Smarty, this API simplification should not
|
||||
require any changes to custom plugins.
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten for better
|
||||
performance. Most notably {html_select_date} and {html_select_time}
|
||||
have been improved vastly. Performance aside, plugins have also been
|
||||
reviewed and generalized in their API. {html_select_date} and
|
||||
{html_select_time} now share almost all available options.
|
||||
|
||||
The escape modifier now knows the $double_encode option, which will
|
||||
prevent entities from being encoded again.
|
||||
|
||||
The capitalize modifier now know the $lc_rest option, which makes sure
|
||||
all letters following a captial letter are lower-cased.
|
||||
|
||||
The count_sentences modifier now accepts (.?!) as
|
||||
legitimate endings of a sentence - previously only (.) was
|
||||
accepted
|
||||
|
||||
The new unescape modifier is there to reverse the effects of the
|
||||
escape modifier. This applies to the escape formats html, htmlall and
|
||||
entity.
|
||||
|
||||
default_template_handler_func
|
||||
|
||||
The invocation of $smarty->$default_template_handler_func had to be
|
||||
altered. Instead of a Smarty_Internal_Template, the fifth argument is
|
||||
now provided with the Smarty instance. New footprint:
|
||||
|
||||
|
||||
/**
|
||||
* Default Template Handler
|
||||
*
|
||||
* called when Smarty's file: resource is unable to load a requested file
|
||||
*
|
||||
* @param string $type resource type (e.g. "file", "string", "eval", "resource")
|
||||
* @param string $name resource name (e.g. "foo/bar.tpl")
|
||||
* @param string &$content template's content
|
||||
* @param integer &$modified template's modification time
|
||||
* @param Smarty $smarty Smarty instance
|
||||
* @return string|boolean path to file or boolean true if $content and $modified
|
||||
* have been filled, boolean false if no default template
|
||||
* could be loaded
|
||||
*/
|
||||
function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) {
|
||||
if (false) {
|
||||
// return corrected filepath
|
||||
return "/tmp/some/foobar.tpl";
|
||||
} elseif (false) {
|
||||
// return a template directly
|
||||
$content = "the template source";
|
||||
$modified = time();
|
||||
return true;
|
||||
} else {
|
||||
// tell smarty that we failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stuff done to the compiler
|
||||
|
||||
Many performance improvements have happened internally. One notable
|
||||
improvement is that all compiled templates are now handled as PHP
|
||||
functions. This speeds up repeated templates tremendously, as each one
|
||||
calls an (in-memory) PHP function instead of performing another file
|
||||
include/scan.
|
||||
|
||||
New Features
|
||||
|
||||
Template syntax
|
||||
|
||||
{block}..{/block}
|
||||
|
||||
The {block} tag has a new hide option flag. It does suppress the block
|
||||
content if no corresponding child block exists.
|
||||
EXAMPLE:
|
||||
parent.tpl
|
||||
{block name=body hide} child content "{$smarty.block.child}" was
|
||||
inserted {block}
|
||||
In the above example the whole block will be suppressed if no child
|
||||
block "body" is existing.
|
||||
|
||||
{setfilter}..{/setfilter}
|
||||
|
||||
The new {setfilter} block tag allows the definition of filters which
|
||||
run on variable output.
|
||||
SYNTAX:
|
||||
{setfilter filter1|filter2|filter3....}
|
||||
Smarty3 will lookup up matching filters in the following search order:
|
||||
1. varibale filter plugin in plugins_dir.
|
||||
2. a valid modifier. A modifier specification will also accept
|
||||
additional parameter like filter2:'foo'
|
||||
3. a PHP function
|
||||
{/setfilter} will turn previous filter setting off again.
|
||||
{setfilter} tags can be nested.
|
||||
EXAMPLE:
|
||||
{setfilter filter1}
|
||||
{$foo}
|
||||
{setfilter filter2}
|
||||
{$bar}
|
||||
{/setfilter}
|
||||
{$buh}
|
||||
{/setfilter}
|
||||
{$blar}
|
||||
In the above example filter1 will run on the output of $foo, filter2
|
||||
on $bar, filter1 again on $buh and no filter on $blar.
|
||||
NOTES:
|
||||
- {$foo nofilter} will suppress the filters
|
||||
- These filters will run in addition to filters defined by
|
||||
registerFilter('variable',...), autoLoadFilter('variable',...) and
|
||||
defined default modifier.
|
||||
- {setfilter} will effect only the current template, not included
|
||||
subtemplates.
|
||||
|
||||
Resource API
|
||||
|
||||
Smarty 3.1 features a new approach to resource management. The
|
||||
Smarty_Resource API allows simple, yet powerful integration of custom
|
||||
resources for templates and configuration files. It offers simple
|
||||
functions for loading data from a custom resource (e.g. database) as
|
||||
well as define new template types adhering to the special
|
||||
non-compiling (e,g, plain php) and non-compile-caching (e.g. eval:
|
||||
resource type) resources.
|
||||
|
||||
See demo/plugins/resource.mysql.php for an example custom database
|
||||
resource.
|
||||
|
||||
Note that old-fashioned registration of callbacks for resource
|
||||
management has been deprecated but is still possible with SmartyBC.
|
||||
|
||||
CacheResource API
|
||||
|
||||
In line with the Resource API, the CacheResource API offers a more
|
||||
comfortable handling of output-cache data. With the
|
||||
Smarty_CacheResource_Custom accessing databases is made simple. With
|
||||
the introduction of Smarty_CacheResource_KeyValueStore the
|
||||
implementation of resources like memcache or APC became a no-brainer;
|
||||
simple hash-based storage systems are now supporting hierarchical
|
||||
output-caches.
|
||||
|
||||
See demo/plugins/cacheresource.mysql.php for an example custom
|
||||
database CacheResource.
|
||||
See demo/plugins/cacheresource.memcache.php for an example custom
|
||||
memcache CacheResource using the KeyValueStore helper.
|
||||
|
||||
Note that old-fashioned registration of $cache_handler is not possible
|
||||
anymore. As the functionality had not been ported to Smarty 3.0.x
|
||||
properly, it has been dropped from 3.1 completely.
|
||||
|
||||
Locking facilities have been implemented to avoid concurrent cache
|
||||
generation. Enable cache locking by setting
|
||||
$smarty->cache_locking = true;
|
||||
|
||||
Relative Paths in Templates (File-Resource)
|
||||
|
||||
As of Smarty 3.1 {include file="../foo.tpl"} and {include
|
||||
file="./foo.tpl"} will resolve relative to the template they're in.
|
||||
Relative paths are available with {include file="..."} and
|
||||
{extends file="..."}. As $smarty->fetch('../foo.tpl') and
|
||||
$smarty->fetch('./foo.tpl') cannot be relative to a template, an
|
||||
exception is thrown.
|
||||
|
||||
Addressing a specific $template_dir
|
||||
|
||||
Smarty 3.1 introduces the $template_dir index notation.
|
||||
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}
|
||||
require the template bar.tpl to be loaded from $template_dir['foo'];
|
||||
Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to
|
||||
define indexes along with the actual directories.
|
||||
|
||||
Mixing Resources in extends-Resource
|
||||
|
||||
Taking the php extends: template resource one step further, it is now
|
||||
possible to mix resources within an extends: call like
|
||||
$smarty->fetch("extends:file:foo.tpl|db:bar.tpl");
|
||||
|
||||
To make eval: and string: resources available to the inheritance
|
||||
chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been
|
||||
introduced. Supplying the base64 or urlencode flags will trigger
|
||||
decoding the TPL_STRING in with either base64_decode() or urldecode().
|
||||
|
||||
extends-Resource in template inheritance
|
||||
|
||||
Template based inheritance may now inherit from php's extends:
|
||||
resource like {extends file="extends:foo.tpl|db:bar.tpl"}.
|
||||
|
||||
New Smarty property escape_html
|
||||
|
||||
$smarty->escape_html = true will autoescape all template variable
|
||||
output by calling htmlspecialchars({$output}, ENT_QUOTES,
|
||||
SMARTY_RESOURCE_CHAR_SET).
|
||||
NOTE:
|
||||
This is a compile time option. If you change the setting you must make
|
||||
sure that the templates get recompiled.
|
||||
|
||||
New option at Smarty property compile_check
|
||||
|
||||
The automatic recompilation of modified templates can now be
|
||||
controlled by the following settings:
|
||||
$smarty->compile_check = COMPILECHECK_OFF (false) - template files
|
||||
will not be checked
|
||||
$smarty->compile_check = COMPILECHECK_ON (true) - template files will
|
||||
always be checked
|
||||
$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will
|
||||
be checked if caching is enabled and there is no existing cache file
|
||||
or it has expired
|
||||
|
||||
Automatic recompilation on Smarty version change
|
||||
|
||||
Templates will now be automatically recompiled on Smarty version
|
||||
changes to avoide incompatibillities in the compiled code. Compiled
|
||||
template checked against the current setting of the SMARTY_VERSION
|
||||
constant.
|
||||
|
||||
default_config_handler_func()
|
||||
|
||||
Analogous to the default_template_handler_func()
|
||||
default_config_handler_func() has been introduced.
|
||||
|
||||
default_plugin_handler_func()
|
||||
|
||||
An optional default_plugin_handler_func() can be defined which gets called
|
||||
by the compiler on tags which can't be resolved internally or by plugins.
|
||||
The default_plugin_handler() can map tags to plugins on the fly.
|
||||
|
||||
New getters/setters
|
||||
|
||||
The following setters/getters will be part of the official
|
||||
documentation, and will be strongly recommended. Direct property
|
||||
access will still work for the foreseeable future... it will be
|
||||
transparently routed through the setters/getters, and consequently a
|
||||
bit slower.
|
||||
|
||||
array|string getTemplateDir( [string $index] )
|
||||
replaces $smarty->template_dir; and $smarty->template_dir[$index];
|
||||
Smarty setTemplateDir( array|string $path )
|
||||
replaces $smarty->template_dir = "foo"; and $smarty->template_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addTemplateDir( array|string $path, [string $index])
|
||||
replaces $smarty->template_dir[] = "bar"; and
|
||||
$smarty->template_dir[$index] = "bar";
|
||||
|
||||
array|string getConfigDir( [string $index] )
|
||||
replaces $smarty->config_dir; and $smarty->config_dir[$index];
|
||||
Smarty setConfigDir( array|string $path )
|
||||
replaces $smarty->config_dir = "foo"; and $smarty->config_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addConfigDir( array|string $path, [string $index])
|
||||
replaces $smarty->config_dir[] = "bar"; and
|
||||
$smarty->config_dir[$index] = "bar";
|
||||
|
||||
array getPluginsDir()
|
||||
replaces $smarty->plugins_dir;
|
||||
Smarty setPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir = "foo";
|
||||
Smarty addPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir[] = "bar";
|
||||
|
||||
string getCompileDir()
|
||||
replaces $smarty->compile_dir;
|
||||
Smarty setCompileDir( string $path )
|
||||
replaces $smarty->compile_dir = "foo";
|
||||
|
||||
string getCacheDir()
|
||||
replaces $smarty->cache_dir;
|
||||
Smarty setCacheDir( string $path )
|
||||
replaces $smarty->cache_dir;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Autoloader
|
||||
*
|
||||
* @package Smarty
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty Autoloader
|
||||
*
|
||||
* @package Smarty
|
||||
* @author Uwe Tews
|
||||
* Usage:
|
||||
* require_once '...path/Autoloader.php';
|
||||
* Smarty_Autoloader::register();
|
||||
* $smarty = new Smarty();
|
||||
* Note: This autoloader is not needed if you use Composer.
|
||||
* Composer will automatically add the classes of the Smarty package to it common autoloader.
|
||||
*/
|
||||
class Smarty_Autoloader
|
||||
{
|
||||
/**
|
||||
* Filepath to Smarty root
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $SMARTY_DIR = '';
|
||||
/**
|
||||
* Filepath to Smarty internal plugins
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $SMARTY_SYSPLUGINS_DIR = '';
|
||||
/**
|
||||
* Array of not existing classes to avoid is_file calls for already tested classes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $unknown = array();
|
||||
/**
|
||||
* Array with Smarty core classes and their filename
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $rootClasses = array('Smarty' => 'Smarty.class.php',
|
||||
'SmartyBC' => 'SmartyBC.class.php',
|
||||
);
|
||||
|
||||
private static $syspluginsClasses = array(
|
||||
'smarty_config_source' => true,
|
||||
'smarty_security' => true,
|
||||
'smarty_cacheresource' => true,
|
||||
'smarty_compiledresource' => true,
|
||||
'smarty_cacheresource_custom' => true,
|
||||
'smarty_cacheresource_keyvaluestore' => true,
|
||||
'smarty_resource' => true,
|
||||
'smarty_resource_custom' => true,
|
||||
'smarty_resource_uncompiled' => true,
|
||||
'smarty_resource_recompiled' => true,
|
||||
'smarty_template_source' => true,
|
||||
'smarty_template_compiled' => true,
|
||||
'smarty_template_cached' => true,
|
||||
'smarty_template_config' => true,
|
||||
'smarty_data' => true,
|
||||
'smarty_variable' => true,
|
||||
'smarty_undefined_variable' => true,
|
||||
'smartyexception' => true,
|
||||
'smartycompilerexception' => true,
|
||||
'smarty_internal_data' => true,
|
||||
'smarty_internal_template' => true,
|
||||
'smarty_internal_templatebase' => true,
|
||||
'smarty_internal_resource_file' => true,
|
||||
'smarty_internal_resource_extends' => true,
|
||||
'smarty_internal_resource_eval' => true,
|
||||
'smarty_internal_resource_string' => true,
|
||||
'smarty_internal_resource_registered' => true,
|
||||
'smarty_internal_extension_codeframe' => true,
|
||||
'smarty_internal_extension_config' => true,
|
||||
'smarty_internal_filter_handler' => true,
|
||||
'smarty_internal_function_call_handler' => true,
|
||||
'smarty_internal_cacheresource_file' => true,
|
||||
'smarty_internal_write_file' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Registers Smarty_Autoloader backward compatible to older installations.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not.
|
||||
*/
|
||||
public static function registerBC($prepend = false)
|
||||
{
|
||||
/**
|
||||
* register the class autoloader
|
||||
*/
|
||||
if (!defined('SMARTY_SPL_AUTOLOAD')) {
|
||||
define('SMARTY_SPL_AUTOLOAD', 0);
|
||||
}
|
||||
if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
|
||||
$registeredAutoLoadFunctions = spl_autoload_functions();
|
||||
if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
|
||||
spl_autoload_register();
|
||||
}
|
||||
} else {
|
||||
self::register($prepend);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers Smarty_Autoloader as an SPL autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not.
|
||||
*/
|
||||
public static function register($prepend = false)
|
||||
{
|
||||
self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . '/';
|
||||
self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR : self::$SMARTY_DIR . 'sysplugins/';
|
||||
if (version_compare(phpversion(), '5.3.0', '>=')) {
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
|
||||
} else {
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles autoloading of classes.
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*/
|
||||
public static function autoload($class)
|
||||
{
|
||||
// Request for Smarty or already unknown class
|
||||
if (isset(self::$unknown[$class])) {
|
||||
return;
|
||||
}
|
||||
$_class = strtolower($class);
|
||||
if (isset(self::$syspluginsClasses[$_class])) {
|
||||
$_class = (self::$syspluginsClasses[$_class] === true) ? $_class : self::$syspluginsClasses[$_class];
|
||||
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
|
||||
require_once $file;
|
||||
return;
|
||||
} elseif (0 !== strpos($_class, 'smarty_internal_')) {
|
||||
if (isset(self::$rootClasses[$class])) {
|
||||
$file = self::$SMARTY_DIR . self::$rootClasses[$class];
|
||||
require_once $file;
|
||||
return;
|
||||
}
|
||||
self::$unknown[$class] = true;
|
||||
return;
|
||||
}
|
||||
$file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
|
||||
if (is_file($file)) {
|
||||
require_once $file;
|
||||
return;
|
||||
}
|
||||
self::$unknown[$class] = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Config_File class.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Smarty mailing list. Send a blank e-mail to
|
||||
* smarty-discussion-subscribe@googlegroups.com
|
||||
*
|
||||
* @link http://www.smarty.net/
|
||||
* @version 2.6.26
|
||||
* @copyright Copyright: 2001-2005 New Digital Group, Inc.
|
||||
* @author Andrei Zmievski <andrei@php.net>
|
||||
* @access public
|
||||
* @package Smarty
|
||||
*/
|
||||
|
||||
/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
|
||||
|
||||
/**
|
||||
* Config file reading class
|
||||
* @package Smarty
|
||||
*/
|
||||
class Config_File {
|
||||
/**#@+
|
||||
* Options
|
||||
* @var boolean
|
||||
*/
|
||||
/**
|
||||
* Controls whether variables with the same name overwrite each other.
|
||||
*/
|
||||
var $overwrite = true;
|
||||
|
||||
/**
|
||||
* Controls whether config values of on/true/yes and off/false/no get
|
||||
* converted to boolean values automatically.
|
||||
*/
|
||||
var $booleanize = true;
|
||||
|
||||
/**
|
||||
* Controls whether hidden config sections/vars are read from the file.
|
||||
*/
|
||||
var $read_hidden = true;
|
||||
|
||||
/**
|
||||
* Controls whether or not to fix mac or dos formatted newlines.
|
||||
* If set to true, \r or \r\n will be changed to \n.
|
||||
*/
|
||||
var $fix_newlines = true;
|
||||
/**#@-*/
|
||||
|
||||
/** @access private */
|
||||
var $_config_path = "";
|
||||
var $_config_data = array();
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Constructs a new config file class.
|
||||
*
|
||||
* @param string $config_path (optional) path to the config files
|
||||
*/
|
||||
function Config_File($config_path = NULL)
|
||||
{
|
||||
if (isset($config_path))
|
||||
$this->set_path($config_path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the path where configuration files can be found.
|
||||
*
|
||||
* @param string $config_path path to the config files
|
||||
*/
|
||||
function set_path($config_path)
|
||||
{
|
||||
if (!empty($config_path)) {
|
||||
if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
|
||||
$this->_trigger_error_msg("Bad config file path '$config_path'");
|
||||
return;
|
||||
}
|
||||
if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
|
||||
$config_path .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
$this->_config_path = $config_path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves config info based on the file, section, and variable name.
|
||||
*
|
||||
* @param string $file_name config file to get info for
|
||||
* @param string $section_name (optional) section to get info for
|
||||
* @param string $var_name (optional) variable to get info for
|
||||
* @return string|array a value or array of values
|
||||
*/
|
||||
function get($file_name, $section_name = NULL, $var_name = NULL)
|
||||
{
|
||||
if (empty($file_name)) {
|
||||
$this->_trigger_error_msg('Empty config file name');
|
||||
return;
|
||||
} else {
|
||||
$file_name = $this->_config_path . $file_name;
|
||||
if (!isset($this->_config_data[$file_name]))
|
||||
$this->load_file($file_name, false);
|
||||
}
|
||||
|
||||
if (!empty($var_name)) {
|
||||
if (empty($section_name)) {
|
||||
return $this->_config_data[$file_name]["vars"][$var_name];
|
||||
} else {
|
||||
if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
|
||||
return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
|
||||
else
|
||||
return array();
|
||||
}
|
||||
} else {
|
||||
if (empty($section_name)) {
|
||||
return (array)$this->_config_data[$file_name]["vars"];
|
||||
} else {
|
||||
if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
|
||||
return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
|
||||
else
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves config info based on the key.
|
||||
*
|
||||
* @param $file_name string config key (filename/section/var)
|
||||
* @return string|array same as get()
|
||||
* @uses get() retrieves information from config file and returns it
|
||||
*/
|
||||
function &get_key($config_key)
|
||||
{
|
||||
list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
|
||||
$result = &$this->get($file_name, $section_name, $var_name);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all loaded config file names.
|
||||
*
|
||||
* @return array an array of loaded config file names
|
||||
*/
|
||||
function get_file_names()
|
||||
{
|
||||
return array_keys($this->_config_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all section names from a loaded file.
|
||||
*
|
||||
* @param string $file_name config file to get section names from
|
||||
* @return array an array of section names from the specified file
|
||||
*/
|
||||
function get_section_names($file_name)
|
||||
{
|
||||
$file_name = $this->_config_path . $file_name;
|
||||
if (!isset($this->_config_data[$file_name])) {
|
||||
$this->_trigger_error_msg("Unknown config file '$file_name'");
|
||||
return;
|
||||
}
|
||||
|
||||
return array_keys($this->_config_data[$file_name]["sections"]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all global or section variable names.
|
||||
*
|
||||
* @param string $file_name config file to get info for
|
||||
* @param string $section_name (optional) section to get info for
|
||||
* @return array an array of variables names from the specified file/section
|
||||
*/
|
||||
function get_var_names($file_name, $section = NULL)
|
||||
{
|
||||
if (empty($file_name)) {
|
||||
$this->_trigger_error_msg('Empty config file name');
|
||||
return;
|
||||
} else if (!isset($this->_config_data[$file_name])) {
|
||||
$this->_trigger_error_msg("Unknown config file '$file_name'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($section))
|
||||
return array_keys($this->_config_data[$file_name]["vars"]);
|
||||
else
|
||||
return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear loaded config data for a certain file or all files.
|
||||
*
|
||||
* @param string $file_name file to clear config data for
|
||||
*/
|
||||
function clear($file_name = NULL)
|
||||
{
|
||||
if ($file_name === NULL)
|
||||
$this->_config_data = array();
|
||||
else if (isset($this->_config_data[$file_name]))
|
||||
$this->_config_data[$file_name] = array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load a configuration file manually.
|
||||
*
|
||||
* @param string $file_name file name to load
|
||||
* @param boolean $prepend_path whether current config path should be
|
||||
* prepended to the filename
|
||||
*/
|
||||
function load_file($file_name, $prepend_path = true)
|
||||
{
|
||||
if ($prepend_path && $this->_config_path != "")
|
||||
$config_file = $this->_config_path . $file_name;
|
||||
else
|
||||
$config_file = $file_name;
|
||||
|
||||
ini_set('track_errors', true);
|
||||
$fp = @fopen($config_file, "r");
|
||||
if (!is_resource($fp)) {
|
||||
$this->_trigger_error_msg("Could not open config file '$config_file'");
|
||||
return false;
|
||||
}
|
||||
|
||||
$contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
|
||||
fclose($fp);
|
||||
|
||||
$this->_config_data[$config_file] = $this->parse_contents($contents);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the contents of a file manually.
|
||||
*
|
||||
* @param string $config_file file name of the related contents
|
||||
* @param string $contents the file-contents to parse
|
||||
*/
|
||||
function set_file_contents($config_file, $contents)
|
||||
{
|
||||
$this->_config_data[$config_file] = $this->parse_contents($contents);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse the source of a configuration file manually.
|
||||
*
|
||||
* @param string $contents the file-contents to parse
|
||||
*/
|
||||
function parse_contents($contents)
|
||||
{
|
||||
if($this->fix_newlines) {
|
||||
// fix mac/dos formatted newlines
|
||||
$contents = preg_replace('!\r\n?!', "\n", $contents);
|
||||
}
|
||||
|
||||
$config_data = array();
|
||||
$config_data['sections'] = array();
|
||||
$config_data['vars'] = array();
|
||||
|
||||
/* reference to fill with data */
|
||||
$vars =& $config_data['vars'];
|
||||
|
||||
/* parse file line by line */
|
||||
preg_match_all('!^.*\r?\n?!m', $contents, $match);
|
||||
$lines = $match[0];
|
||||
for ($i=0, $count=count($lines); $i<$count; $i++) {
|
||||
$line = $lines[$i];
|
||||
if (empty($line)) continue;
|
||||
|
||||
if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
|
||||
/* section found */
|
||||
if (substr($match[1], 0, 1) == '.') {
|
||||
/* hidden section */
|
||||
if ($this->read_hidden) {
|
||||
$section_name = substr($match[1], 1);
|
||||
} else {
|
||||
/* break reference to $vars to ignore hidden section */
|
||||
unset($vars);
|
||||
$vars = array();
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$section_name = $match[1];
|
||||
}
|
||||
if (!isset($config_data['sections'][$section_name]))
|
||||
$config_data['sections'][$section_name] = array('vars' => array());
|
||||
$vars =& $config_data['sections'][$section_name]['vars'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
|
||||
/* variable found */
|
||||
$var_name = rtrim($match[1]);
|
||||
if (strpos($match[2], '"""') === 0) {
|
||||
/* handle multiline-value */
|
||||
$lines[$i] = substr($match[2], 3);
|
||||
$var_value = '';
|
||||
while ($i<$count) {
|
||||
if (($pos = strpos($lines[$i], '"""')) === false) {
|
||||
$var_value .= $lines[$i++];
|
||||
} else {
|
||||
/* end of multiline-value */
|
||||
$var_value .= substr($lines[$i], 0, $pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$booleanize = false;
|
||||
|
||||
} else {
|
||||
/* handle simple value */
|
||||
$var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
|
||||
$booleanize = $this->booleanize;
|
||||
|
||||
}
|
||||
$this->_set_config_var($vars, $var_name, $var_value, $booleanize);
|
||||
}
|
||||
/* else unparsable line / means it is a comment / means ignore it */
|
||||
}
|
||||
return $config_data;
|
||||
}
|
||||
|
||||
/**#@+ @access private */
|
||||
/**
|
||||
* @param array &$container
|
||||
* @param string $var_name
|
||||
* @param mixed $var_value
|
||||
* @param boolean $booleanize determines whether $var_value is converted to
|
||||
* to true/false
|
||||
*/
|
||||
function _set_config_var(&$container, $var_name, $var_value, $booleanize)
|
||||
{
|
||||
if (substr($var_name, 0, 1) == '.') {
|
||||
if (!$this->read_hidden)
|
||||
return;
|
||||
else
|
||||
$var_name = substr($var_name, 1);
|
||||
}
|
||||
|
||||
if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
|
||||
$this->_trigger_error_msg("Bad variable name '$var_name'");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($booleanize) {
|
||||
if (preg_match("/^(on|true|yes)$/i", $var_value))
|
||||
$var_value = true;
|
||||
else if (preg_match("/^(off|false|no)$/i", $var_value))
|
||||
$var_value = false;
|
||||
}
|
||||
|
||||
if (!isset($container[$var_name]) || $this->overwrite)
|
||||
$container[$var_name] = $var_value;
|
||||
else {
|
||||
settype($container[$var_name], 'array');
|
||||
$container[$var_name][] = $var_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @uses trigger_error() creates a PHP warning/error
|
||||
* @param string $error_msg
|
||||
* @param integer $error_type one of
|
||||
*/
|
||||
function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
|
||||
{
|
||||
trigger_error("Config_File error: $error_msg", $error_type);
|
||||
}
|
||||
/**#@-*/
|
||||
}
|
||||
|
||||
?>
|
||||
+1483
-1642
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,448 @@
|
||||
<?php
|
||||
/**
|
||||
* Project: Smarty: the PHP compiling template engine
|
||||
* File: SmartyBC.class.php
|
||||
* SVN: $Id: $
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Smarty mailing list. Send a blank e-mail to
|
||||
* smarty-discussion-subscribe@googlegroups.com
|
||||
*
|
||||
* @link http://www.smarty.net/
|
||||
* @copyright 2008 New Digital Group, Inc.
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Uwe Tews
|
||||
* @author Rodney Rehm
|
||||
* @package Smarty
|
||||
*/
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(dirname(__FILE__) . '/Smarty.class.php');
|
||||
|
||||
/**
|
||||
* Smarty Backward Compatability Wrapper Class
|
||||
*
|
||||
* @package Smarty
|
||||
*/
|
||||
class SmartyBC extends Smarty
|
||||
{
|
||||
/**
|
||||
* Smarty 2 BC
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $_version = self::SMARTY_VERSION;
|
||||
|
||||
/**
|
||||
* Initialize new SmartyBC object
|
||||
*
|
||||
* @param array $options options to set during initialization, e.g. array( 'forceCompile' => false )
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for assign_by_ref
|
||||
*
|
||||
* @param string $tpl_var the template variable name
|
||||
* @param mixed &$value the referenced value to assign
|
||||
*/
|
||||
public function assign_by_ref($tpl_var, &$value)
|
||||
{
|
||||
$this->assignByRef($tpl_var, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for append_by_ref
|
||||
*
|
||||
* @param string $tpl_var the template variable name
|
||||
* @param mixed &$value the referenced value to append
|
||||
* @param boolean $merge flag if array elements shall be merged
|
||||
*/
|
||||
public function append_by_ref($tpl_var, &$value, $merge = false)
|
||||
{
|
||||
$this->appendByRef($tpl_var, $value, $merge);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the given assigned template variable.
|
||||
*
|
||||
* @param string $tpl_var the template variable to clear
|
||||
*/
|
||||
public function clear_assign($tpl_var)
|
||||
{
|
||||
$this->clearAssign($tpl_var);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers custom function to be used in templates
|
||||
*
|
||||
* @param string $function the name of the template function
|
||||
* @param string $function_impl the name of the PHP function to register
|
||||
* @param bool $cacheable
|
||||
* @param mixed $cache_attrs
|
||||
*/
|
||||
public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null)
|
||||
{
|
||||
$this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters custom function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
*/
|
||||
public function unregister_function($function)
|
||||
{
|
||||
$this->unregisterPlugin('function', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers object to be used in templates
|
||||
*
|
||||
* @param string $object name of template object
|
||||
* @param object $object_impl the referenced PHP object to register
|
||||
* @param array $allowed list of allowed methods (empty = all)
|
||||
* @param boolean $smarty_args smarty argument format, else traditional
|
||||
* @param array $block_methods list of methods that are block format
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @internal param array $block_functs list of methods that are block format
|
||||
*/
|
||||
public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
|
||||
{
|
||||
settype($allowed, 'array');
|
||||
settype($smarty_args, 'boolean');
|
||||
$this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters object
|
||||
*
|
||||
* @param string $object name of template object
|
||||
*/
|
||||
public function unregister_object($object)
|
||||
{
|
||||
$this->unregisterObject($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers block function to be used in templates
|
||||
*
|
||||
* @param string $block name of template block
|
||||
* @param string $block_impl PHP function to register
|
||||
* @param bool $cacheable
|
||||
* @param mixed $cache_attrs
|
||||
*/
|
||||
public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null)
|
||||
{
|
||||
$this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters block function
|
||||
*
|
||||
* @param string $block name of template function
|
||||
*/
|
||||
public function unregister_block($block)
|
||||
{
|
||||
$this->unregisterPlugin('block', $block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers compiler function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
* @param string $function_impl name of PHP function to register
|
||||
* @param bool $cacheable
|
||||
*/
|
||||
public function register_compiler_function($function, $function_impl, $cacheable = true)
|
||||
{
|
||||
$this->registerPlugin('compiler', $function, $function_impl, $cacheable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters compiler function
|
||||
*
|
||||
* @param string $function name of template function
|
||||
*/
|
||||
public function unregister_compiler_function($function)
|
||||
{
|
||||
$this->unregisterPlugin('compiler', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers modifier to be used in templates
|
||||
*
|
||||
* @param string $modifier name of template modifier
|
||||
* @param string $modifier_impl name of PHP function to register
|
||||
*/
|
||||
public function register_modifier($modifier, $modifier_impl)
|
||||
{
|
||||
$this->registerPlugin('modifier', $modifier, $modifier_impl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters modifier
|
||||
*
|
||||
* @param string $modifier name of template modifier
|
||||
*/
|
||||
public function unregister_modifier($modifier)
|
||||
{
|
||||
$this->unregisterPlugin('modifier', $modifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a resource to fetch a template
|
||||
*
|
||||
* @param string $type name of resource
|
||||
* @param array $functions array of functions to handle resource
|
||||
*/
|
||||
public function register_resource($type, $functions)
|
||||
{
|
||||
$this->registerResource($type, $functions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a resource
|
||||
*
|
||||
* @param string $type name of resource
|
||||
*/
|
||||
public function unregister_resource($type)
|
||||
{
|
||||
$this->unregisterResource($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a prefilter function to apply
|
||||
* to a template before compiling
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_prefilter($function)
|
||||
{
|
||||
$this->registerFilter('pre', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a prefilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_prefilter($function)
|
||||
{
|
||||
$this->unregisterFilter('pre', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a postfilter function to apply
|
||||
* to a compiled template after compilation
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_postfilter($function)
|
||||
{
|
||||
$this->registerFilter('post', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a postfilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_postfilter($function)
|
||||
{
|
||||
$this->unregisterFilter('post', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an output filter function to apply
|
||||
* to a template output
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function register_outputfilter($function)
|
||||
{
|
||||
$this->registerFilter('output', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters an outputfilter function
|
||||
*
|
||||
* @param callable $function
|
||||
*/
|
||||
public function unregister_outputfilter($function)
|
||||
{
|
||||
$this->unregisterFilter('output', $function);
|
||||
}
|
||||
|
||||
/**
|
||||
* load a filter of specified type and name
|
||||
*
|
||||
* @param string $type filter type
|
||||
* @param string $name filter name
|
||||
*/
|
||||
public function load_filter($type, $name)
|
||||
{
|
||||
$this->loadFilter($type, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear cached content for the given template and cache id
|
||||
*
|
||||
* @param string $tpl_file name of template file
|
||||
* @param string $cache_id name of cache_id
|
||||
* @param string $compile_id name of compile_id
|
||||
* @param string $exp_time expiration time
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
|
||||
{
|
||||
return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear the entire contents of cache (all templates)
|
||||
*
|
||||
* @param string $exp_time expire time
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function clear_all_cache($exp_time = null)
|
||||
{
|
||||
return $this->clearCache(null, null, null, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* test to see if valid cache exists for this template
|
||||
*
|
||||
* @param string $tpl_file name of template file
|
||||
* @param string $cache_id
|
||||
* @param string $compile_id
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
|
||||
{
|
||||
return $this->isCached($tpl_file, $cache_id, $compile_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear all the assigned template variables.
|
||||
*/
|
||||
public function clear_all_assign()
|
||||
{
|
||||
$this->clearAllAssign();
|
||||
}
|
||||
|
||||
/**
|
||||
* clears compiled version of specified template resource,
|
||||
* or all compiled template files if one is not specified.
|
||||
* This function is for advanced use only, not normally needed.
|
||||
*
|
||||
* @param string $tpl_file
|
||||
* @param string $compile_id
|
||||
* @param string $exp_time
|
||||
*
|
||||
* @return boolean results of {@link smarty_core_rm_auto()}
|
||||
*/
|
||||
public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
|
||||
{
|
||||
return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether requested template exists.
|
||||
*
|
||||
* @param string $tpl_file
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function template_exists($tpl_file)
|
||||
{
|
||||
return $this->templateExists($tpl_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing template variables
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_template_vars($name = null)
|
||||
{
|
||||
return $this->getTemplateVars($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing config variables
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_config_vars($name = null)
|
||||
{
|
||||
return $this->getConfigVars($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* load configuration values
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $section
|
||||
* @param string $scope
|
||||
*/
|
||||
public function config_load($file, $section = null, $scope = 'global')
|
||||
{
|
||||
$this->ConfigLoad($file, $section, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a reference to a registered object
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_registered_object($name)
|
||||
{
|
||||
return $this->getRegisteredObject($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clear configuration values
|
||||
*
|
||||
* @param string $var
|
||||
*/
|
||||
public function clear_config($var = null)
|
||||
{
|
||||
$this->clearConfig($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger Smarty error
|
||||
*
|
||||
* @param string $error_msg
|
||||
* @param integer $error_type
|
||||
*/
|
||||
public function trigger_error($error_msg, $error_type = E_USER_WARNING)
|
||||
{
|
||||
trigger_error("Smarty error: $error_msg", $error_type);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+135
-132
@@ -1,157 +1,160 @@
|
||||
{* Smarty *}
|
||||
{* debug.tpl, last updated version 2.1.0 *}
|
||||
{assign_debug_info}
|
||||
{capture assign=debug_output}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Smarty Debug Console</title>
|
||||
{literal}
|
||||
<style type="text/css">
|
||||
/* <![CDATA[ */
|
||||
body, h1, h2, td, th, p {
|
||||
font-family: sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 0.9em;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
{capture name='_smarty_debug' assign=debug_output}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>Smarty Debug Console</title>
|
||||
<style type="text/css">
|
||||
{literal}
|
||||
body, h1, h2, h3, td, th, p {
|
||||
font-family: sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 0.9em;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
padding: 2px;
|
||||
background-color: #f0c040;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
padding: 2px;
|
||||
background-color: #f0c040;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: #9B410E;
|
||||
color: white;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
h2 {
|
||||
background-color: #9B410E;
|
||||
color: white;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
h3 {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
font-size: 0.7em;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: black;
|
||||
}
|
||||
body {
|
||||
background: black;
|
||||
}
|
||||
|
||||
p, table, div {
|
||||
background: #f0ead8;
|
||||
}
|
||||
p, table, div {
|
||||
background: #f0ead8;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th, td {
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
width: 50%;
|
||||
}
|
||||
th, td {
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
color: green;
|
||||
}
|
||||
td {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.odd {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.odd {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.even {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.even {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.exectime {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
.exectime {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#table_assigned_vars th {
|
||||
color: blue;
|
||||
}
|
||||
#bold div {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
#blue h3 {
|
||||
color: blue;
|
||||
}
|
||||
#normal div {
|
||||
color: black;
|
||||
font-weight: normal;
|
||||
}
|
||||
#table_assigned_vars th {
|
||||
color: blue;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#table_config_vars th {
|
||||
color: maroon;
|
||||
}
|
||||
/* ]]> */
|
||||
</style>
|
||||
{/literal}
|
||||
</head>
|
||||
<body>
|
||||
#table_config_vars th {
|
||||
color: maroon;
|
||||
}
|
||||
|
||||
<h1>Smarty Debug Console</h1>
|
||||
{/literal}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>included templates & config files (load time in seconds)</h2>
|
||||
<h1>Smarty {Smarty::SMARTY_VERSION} Debug Console
|
||||
- {if isset($template_name)}{$template_name|debug_print_var nofilter} {/if}{if !empty($template_data)}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
|
||||
|
||||
<div>
|
||||
{section name=templates loop=$_debug_tpls}
|
||||
{section name=indent loop=$_debug_tpls[templates].depth} {/section}
|
||||
<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
|
||||
{$_debug_tpls[templates].filename|escape:html}</font>
|
||||
{if isset($_debug_tpls[templates].exec_time)}
|
||||
<span class="exectime">
|
||||
({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
|
||||
{if %templates.index% eq 0}(total){/if}
|
||||
</span>
|
||||
{if !empty($template_data)}
|
||||
<h2>included templates & config files (load time in seconds)</h2>
|
||||
<div>
|
||||
{foreach $template_data as $template}
|
||||
<font color=brown>{$template.name}</font>
|
||||
<br> <span class="exectime">
|
||||
(compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
|
||||
</span>
|
||||
<br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
<br />
|
||||
{sectionelse}
|
||||
<p>no templates included</p>
|
||||
{/section}
|
||||
</div>
|
||||
|
||||
<h2>assigned template variables</h2>
|
||||
<h2>assigned template variables</h2>
|
||||
|
||||
<table id="table_assigned_vars">
|
||||
{section name=vars loop=$_debug_keys}
|
||||
<tr class="{cycle values="odd,even"}">
|
||||
<th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
|
||||
<td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
|
||||
{sectionelse}
|
||||
<tr><td><p>no template variables assigned</p></td></tr>
|
||||
{/section}
|
||||
</table>
|
||||
<table id="table_assigned_vars">
|
||||
{foreach $assigned_vars as $vars}
|
||||
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
|
||||
<td><h3><font color=blue>${$vars@key}</font></h3>
|
||||
{if isset($vars['nocache'])}<b>Nocache</b></br>{/if}
|
||||
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
|
||||
</td>
|
||||
<td><h3>Value</h3>{$vars['value']|debug_print_var:10:80 nofilter}</td>
|
||||
<td>{if isset($vars['attributes'])}<h3>Attributes</h3>{$vars['attributes']|debug_print_var nofilter} {/if}</td>
|
||||
{/foreach}
|
||||
</table>
|
||||
|
||||
<h2>assigned config file variables (outer template scope)</h2>
|
||||
<h2>assigned config file variables</h2>
|
||||
|
||||
<table id="table_config_vars">
|
||||
{section name=config_vars loop=$_debug_config_keys}
|
||||
<tr class="{cycle values="odd,even"}">
|
||||
<th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
|
||||
<td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
|
||||
{sectionelse}
|
||||
<tr><td><p>no config vars assigned</p></td></tr>
|
||||
{/section}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
<table id="table_config_vars">
|
||||
{foreach $config_vars as $vars}
|
||||
<tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">
|
||||
<td><h3><font color=blue>#{$vars@key}#</font></h3>
|
||||
{if isset($vars['scope'])}<b>Origin:</b> {$vars['scope']|debug_print_var nofilter}{/if}
|
||||
</td>
|
||||
<td>{$vars['value']|debug_print_var:10:80 nofilter}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
{/capture}
|
||||
{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
|
||||
{$debug_output}
|
||||
{else}
|
||||
<script type="text/javascript">
|
||||
// <![CDATA[
|
||||
if ( self.name == '' ) {ldelim}
|
||||
var title = 'Console';
|
||||
{rdelim}
|
||||
else {ldelim}
|
||||
var title = 'Console_' + self.name;
|
||||
{rdelim}
|
||||
_smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
|
||||
_smarty_console.document.write('{$debug_output|escape:'javascript'}');
|
||||
{$id = ''}
|
||||
{if $display_mode}{$id = "$offset$template_name"|md5}{/if}
|
||||
_smarty_console = window.open("", "console{$id}", "width=1024,height=600,left={$offset},top={$offset},resizable,scrollbars=yes");
|
||||
_smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
|
||||
_smarty_console.document.close();
|
||||
// ]]>
|
||||
</script>
|
||||
{/if}
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* assemble filepath of requested plugin
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @return string|false
|
||||
*/
|
||||
function smarty_core_assemble_plugin_filepath($params, &$smarty)
|
||||
{
|
||||
static $_filepaths_cache = array();
|
||||
|
||||
$_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
|
||||
if (isset($_filepaths_cache[$_plugin_filename])) {
|
||||
return $_filepaths_cache[$_plugin_filename];
|
||||
}
|
||||
$_return = false;
|
||||
|
||||
foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
|
||||
|
||||
$_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
|
||||
|
||||
// see if path is relative
|
||||
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
|
||||
$_relative_paths[] = $_plugin_dir;
|
||||
// relative path, see if it is in the SMARTY_DIR
|
||||
if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
|
||||
$_return = SMARTY_DIR . $_plugin_filepath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// try relative to cwd (or absolute)
|
||||
if (@is_readable($_plugin_filepath)) {
|
||||
$_return = $_plugin_filepath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($_return === false) {
|
||||
// still not found, try PHP include_path
|
||||
if(isset($_relative_paths)) {
|
||||
foreach ((array)$_relative_paths as $_plugin_dir) {
|
||||
|
||||
$_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
|
||||
|
||||
$_params = array('file_path' => $_plugin_filepath);
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
|
||||
if(smarty_core_get_include_path($_params, $smarty)) {
|
||||
$_return = $_params['new_file_path'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$_filepaths_cache[$_plugin_filename] = $_return;
|
||||
return $_return;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty assign_smarty_interface core plugin
|
||||
*
|
||||
* Type: core<br>
|
||||
* Name: assign_smarty_interface<br>
|
||||
* Purpose: assign the $smarty interface variable
|
||||
* @param array Format: null
|
||||
* @param Smarty
|
||||
*/
|
||||
function smarty_core_assign_smarty_interface($params, &$smarty)
|
||||
{
|
||||
if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$_globals_map = array('g' => 'HTTP_GET_VARS',
|
||||
'p' => 'HTTP_POST_VARS',
|
||||
'c' => 'HTTP_COOKIE_VARS',
|
||||
's' => 'HTTP_SERVER_VARS',
|
||||
'e' => 'HTTP_ENV_VARS');
|
||||
|
||||
$_smarty_vars_request = array();
|
||||
|
||||
foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
|
||||
if (isset($_globals_map[$_c])) {
|
||||
$_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
|
||||
}
|
||||
}
|
||||
$_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
|
||||
|
||||
$smarty->_smarty_vars['request'] = $_smarty_vars_request;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* create full directory structure
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
|
||||
// $dir
|
||||
|
||||
function smarty_core_create_dir_structure($params, &$smarty)
|
||||
{
|
||||
if (!file_exists($params['dir'])) {
|
||||
$_open_basedir_ini = ini_get('open_basedir');
|
||||
|
||||
if (DIRECTORY_SEPARATOR=='/') {
|
||||
/* unix-style paths */
|
||||
$_dir = $params['dir'];
|
||||
$_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
|
||||
if($_use_open_basedir = !empty($_open_basedir_ini)) {
|
||||
$_open_basedirs = explode(':', $_open_basedir_ini);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* other-style paths */
|
||||
$_dir = str_replace('\\','/', $params['dir']);
|
||||
$_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
|
||||
if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
|
||||
/* leading "//" for network volume, or "[letter]:/" for full path */
|
||||
$_new_dir = $_root_dir[1];
|
||||
/* remove drive-letter from _dir_parts */
|
||||
if (isset($_root_dir[3])) array_shift($_dir_parts);
|
||||
|
||||
} else {
|
||||
$_new_dir = str_replace('\\', '/', getcwd()).'/';
|
||||
|
||||
}
|
||||
|
||||
if($_use_open_basedir = !empty($_open_basedir_ini)) {
|
||||
$_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* all paths use "/" only from here */
|
||||
foreach ($_dir_parts as $_dir_part) {
|
||||
$_new_dir .= $_dir_part;
|
||||
|
||||
if ($_use_open_basedir) {
|
||||
// do not attempt to test or make directories outside of open_basedir
|
||||
$_make_new_dir = false;
|
||||
foreach ($_open_basedirs as $_open_basedir) {
|
||||
if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
|
||||
$_make_new_dir = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$_make_new_dir = true;
|
||||
}
|
||||
|
||||
if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
|
||||
$smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
|
||||
return false;
|
||||
}
|
||||
$_new_dir .= '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty debug_console function plugin
|
||||
*
|
||||
* Type: core<br>
|
||||
* Name: display_debug_console<br>
|
||||
* Purpose: display the javascript debug console window
|
||||
* @param array Format: null
|
||||
* @param Smarty
|
||||
*/
|
||||
function smarty_core_display_debug_console($params, &$smarty)
|
||||
{
|
||||
// we must force compile the debug template in case the environment
|
||||
// changed between separate applications.
|
||||
|
||||
if(empty($smarty->debug_tpl)) {
|
||||
// set path to debug template from SMARTY_DIR
|
||||
$smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
|
||||
if($smarty->security && is_file($smarty->debug_tpl)) {
|
||||
$smarty->secure_dir[] = realpath($smarty->debug_tpl);
|
||||
}
|
||||
$smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
|
||||
}
|
||||
|
||||
$_ldelim_orig = $smarty->left_delimiter;
|
||||
$_rdelim_orig = $smarty->right_delimiter;
|
||||
|
||||
$smarty->left_delimiter = '{';
|
||||
$smarty->right_delimiter = '}';
|
||||
|
||||
$_compile_id_orig = $smarty->_compile_id;
|
||||
$smarty->_compile_id = null;
|
||||
|
||||
$_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
|
||||
if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
|
||||
{
|
||||
ob_start();
|
||||
$smarty->_include($_compile_path);
|
||||
$_results = ob_get_contents();
|
||||
ob_end_clean();
|
||||
} else {
|
||||
$_results = '';
|
||||
}
|
||||
|
||||
$smarty->_compile_id = $_compile_id_orig;
|
||||
|
||||
$smarty->left_delimiter = $_ldelim_orig;
|
||||
$smarty->right_delimiter = $_rdelim_orig;
|
||||
|
||||
return $_results;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get path to file from include_path
|
||||
*
|
||||
* @param string $file_path
|
||||
* @param string $new_file_path
|
||||
* @return boolean
|
||||
* @staticvar array|null
|
||||
*/
|
||||
|
||||
// $file_path, &$new_file_path
|
||||
|
||||
function smarty_core_get_include_path(&$params, &$smarty)
|
||||
{
|
||||
static $_path_array = null;
|
||||
|
||||
if(!isset($_path_array)) {
|
||||
$_ini_include_path = ini_get('include_path');
|
||||
|
||||
if(strstr($_ini_include_path,';')) {
|
||||
// windows pathnames
|
||||
$_path_array = explode(';',$_ini_include_path);
|
||||
} else {
|
||||
$_path_array = explode(':',$_ini_include_path);
|
||||
}
|
||||
}
|
||||
foreach ($_path_array as $_include_path) {
|
||||
if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
|
||||
$params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get seconds and microseconds
|
||||
* @return double
|
||||
*/
|
||||
function smarty_core_get_microtime($params, &$smarty)
|
||||
{
|
||||
$mtime = microtime();
|
||||
$mtime = explode(" ", $mtime);
|
||||
$mtime = (double)($mtime[1]) + (double)($mtime[0]);
|
||||
return ($mtime);
|
||||
}
|
||||
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves PHP script resource
|
||||
*
|
||||
* sets $php_resource to the returned resource
|
||||
* @param string $resource
|
||||
* @param string $resource_type
|
||||
* @param $php_resource
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function smarty_core_get_php_resource(&$params, &$smarty)
|
||||
{
|
||||
|
||||
$params['resource_base_path'] = $smarty->trusted_dir;
|
||||
$smarty->_parse_resource_name($params, $smarty);
|
||||
|
||||
/*
|
||||
* Find out if the resource exists.
|
||||
*/
|
||||
|
||||
if ($params['resource_type'] == 'file') {
|
||||
$_readable = false;
|
||||
if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
|
||||
$_readable = true;
|
||||
} else {
|
||||
// test for file in include_path
|
||||
$_params = array('file_path' => $params['resource_name']);
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
|
||||
if(smarty_core_get_include_path($_params, $smarty)) {
|
||||
$_include_path = $_params['new_file_path'];
|
||||
$_readable = true;
|
||||
}
|
||||
}
|
||||
} else if ($params['resource_type'] != 'file') {
|
||||
$_template_source = null;
|
||||
$_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
|
||||
&& call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
|
||||
array($params['resource_name'], &$_template_source, &$smarty));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the error function, depending on which class calls us.
|
||||
*/
|
||||
if (method_exists($smarty, '_syntax_error')) {
|
||||
$_error_funcc = '_syntax_error';
|
||||
} else {
|
||||
$_error_funcc = 'trigger_error';
|
||||
}
|
||||
|
||||
if ($_readable) {
|
||||
if ($smarty->security) {
|
||||
require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
|
||||
if (!smarty_core_is_trusted($params, $smarty)) {
|
||||
$smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($params['resource_type'] == 'file') {
|
||||
$params['php_resource'] = $params['resource_name'];
|
||||
} else {
|
||||
$params['php_resource'] = $_template_source;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* determines if a resource is secure or not.
|
||||
*
|
||||
* @param string $resource_type
|
||||
* @param string $resource_name
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
// $resource_type, $resource_name
|
||||
|
||||
function smarty_core_is_secure($params, &$smarty)
|
||||
{
|
||||
if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($params['resource_type'] == 'file') {
|
||||
$_rp = realpath($params['resource_name']);
|
||||
if (isset($params['resource_base_path'])) {
|
||||
foreach ((array)$params['resource_base_path'] as $curr_dir) {
|
||||
if ( ($_cd = realpath($curr_dir)) !== false &&
|
||||
strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
|
||||
substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($smarty->secure_dir)) {
|
||||
foreach ((array)$smarty->secure_dir as $curr_dir) {
|
||||
if ( ($_cd = realpath($curr_dir)) !== false) {
|
||||
if($_cd == $_rp) {
|
||||
return true;
|
||||
} elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
|
||||
substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// resource is not on local file system
|
||||
return call_user_func_array(
|
||||
$smarty->_plugins['resource'][$params['resource_type']][0][2],
|
||||
array($params['resource_name'], &$smarty));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* determines if a resource is trusted or not
|
||||
*
|
||||
* @param string $resource_type
|
||||
* @param string $resource_name
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
// $resource_type, $resource_name
|
||||
|
||||
function smarty_core_is_trusted($params, &$smarty)
|
||||
{
|
||||
$_smarty_trusted = false;
|
||||
if ($params['resource_type'] == 'file') {
|
||||
if (!empty($smarty->trusted_dir)) {
|
||||
$_rp = realpath($params['resource_name']);
|
||||
foreach ((array)$smarty->trusted_dir as $curr_dir) {
|
||||
if (!empty($curr_dir) && is_readable ($curr_dir)) {
|
||||
$_cd = realpath($curr_dir);
|
||||
if (strncmp($_rp, $_cd, strlen($_cd)) == 0
|
||||
&& substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
|
||||
$_smarty_trusted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// resource is not on local file system
|
||||
$_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
|
||||
array($params['resource_name'], $smarty));
|
||||
}
|
||||
|
||||
return $_smarty_trusted;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load requested plugins
|
||||
*
|
||||
* @param array $plugins
|
||||
*/
|
||||
|
||||
// $plugins
|
||||
|
||||
function smarty_core_load_plugins($params, &$smarty)
|
||||
{
|
||||
|
||||
foreach ($params['plugins'] as $_plugin_info) {
|
||||
list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
|
||||
$_plugin = &$smarty->_plugins[$_type][$_name];
|
||||
|
||||
/*
|
||||
* We do not load plugin more than once for each instance of Smarty.
|
||||
* The following code checks for that. The plugin can also be
|
||||
* registered dynamically at runtime, in which case template file
|
||||
* and line number will be unknown, so we fill them in.
|
||||
*
|
||||
* The final element of the info array is a flag that indicates
|
||||
* whether the dynamically registered plugin function has been
|
||||
* checked for existence yet or not.
|
||||
*/
|
||||
if (isset($_plugin)) {
|
||||
if (empty($_plugin[3])) {
|
||||
if (!is_callable($_plugin[0])) {
|
||||
$smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
|
||||
} else {
|
||||
$_plugin[1] = $_tpl_file;
|
||||
$_plugin[2] = $_tpl_line;
|
||||
$_plugin[3] = true;
|
||||
if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else if ($_type == 'insert') {
|
||||
/*
|
||||
* For backwards compatibility, we check for insert functions in
|
||||
* the symbol table before trying to load them as a plugin.
|
||||
*/
|
||||
$_plugin_func = 'insert_' . $_name;
|
||||
if (function_exists($_plugin_func)) {
|
||||
$_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
|
||||
|
||||
if (! $_found = ($_plugin_file != false)) {
|
||||
$_message = "could not load plugin file '$_type.$_name.php'\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* If plugin file is found, it -must- provide the properly named
|
||||
* plugin function. In case it doesn't, simply output the error and
|
||||
* do not fall back on any other method.
|
||||
*/
|
||||
if ($_found) {
|
||||
include_once $_plugin_file;
|
||||
|
||||
$_plugin_func = 'smarty_' . $_type . '_' . $_name;
|
||||
if (!function_exists($_plugin_func)) {
|
||||
$smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* In case of insert plugins, their code may be loaded later via
|
||||
* 'script' attribute.
|
||||
*/
|
||||
else if ($_type == 'insert' && $_delayed_loading) {
|
||||
$_plugin_func = 'smarty_' . $_type . '_' . $_name;
|
||||
$_found = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Plugin specific processing and error checking.
|
||||
*/
|
||||
if (!$_found) {
|
||||
if ($_type == 'modifier') {
|
||||
/*
|
||||
* In case modifier falls back on using PHP functions
|
||||
* directly, we only allow those specified in the security
|
||||
* context.
|
||||
*/
|
||||
if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
|
||||
$_message = "(secure mode) modifier '$_name' is not allowed";
|
||||
} else {
|
||||
if (!function_exists($_name)) {
|
||||
$_message = "modifier '$_name' is not implemented";
|
||||
} else {
|
||||
$_plugin_func = $_name;
|
||||
$_found = true;
|
||||
}
|
||||
}
|
||||
} else if ($_type == 'function') {
|
||||
/*
|
||||
* This is a catch-all situation.
|
||||
*/
|
||||
$_message = "unknown tag - '$_name'";
|
||||
}
|
||||
}
|
||||
|
||||
if ($_found) {
|
||||
$smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
|
||||
} else {
|
||||
// output error
|
||||
$smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* load a resource plugin
|
||||
*
|
||||
* @param string $type
|
||||
*/
|
||||
|
||||
// $type
|
||||
|
||||
function smarty_core_load_resource_plugin($params, &$smarty)
|
||||
{
|
||||
/*
|
||||
* Resource plugins are not quite like the other ones, so they are
|
||||
* handled differently. The first element of plugin info is the array of
|
||||
* functions provided by the plugin, the second one indicates whether
|
||||
* all of them exist or not.
|
||||
*/
|
||||
|
||||
$_plugin = &$smarty->_plugins['resource'][$params['type']];
|
||||
if (isset($_plugin)) {
|
||||
if (!$_plugin[1] && count($_plugin[0])) {
|
||||
$_plugin[1] = true;
|
||||
foreach ($_plugin[0] as $_plugin_func) {
|
||||
if (!is_callable($_plugin_func)) {
|
||||
$_plugin[1] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$_plugin[1]) {
|
||||
$smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
|
||||
$_found = ($_plugin_file != false);
|
||||
|
||||
if ($_found) { /*
|
||||
* If the plugin file is found, it -must- provide the properly named
|
||||
* plugin functions.
|
||||
*/
|
||||
include_once($_plugin_file);
|
||||
|
||||
/*
|
||||
* Locate functions that we require the plugin to provide.
|
||||
*/
|
||||
$_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
|
||||
$_resource_funcs = array();
|
||||
foreach ($_resource_ops as $_op) {
|
||||
$_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
|
||||
if (!function_exists($_plugin_func)) {
|
||||
$smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
|
||||
return;
|
||||
} else {
|
||||
$_resource_funcs[] = $_plugin_func;
|
||||
}
|
||||
}
|
||||
|
||||
$smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replace cached inserts with the actual results
|
||||
*
|
||||
* @param string $results
|
||||
* @return string
|
||||
*/
|
||||
function smarty_core_process_cached_inserts($params, &$smarty)
|
||||
{
|
||||
preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
|
||||
$params['results'], $match);
|
||||
list($cached_inserts, $insert_args) = $match;
|
||||
|
||||
for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
$debug_start_time = smarty_core_get_microtime($_params, $smarty);
|
||||
}
|
||||
|
||||
$args = unserialize($insert_args[$i]);
|
||||
$name = $args['name'];
|
||||
|
||||
if (isset($args['script'])) {
|
||||
$_params = array('resource_name' => $smarty->_dequote($args['script']));
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
|
||||
if(!smarty_core_get_php_resource($_params, $smarty)) {
|
||||
return false;
|
||||
}
|
||||
$resource_type = $_params['resource_type'];
|
||||
$php_resource = $_params['php_resource'];
|
||||
|
||||
|
||||
if ($resource_type == 'file') {
|
||||
$smarty->_include($php_resource, true);
|
||||
} else {
|
||||
$smarty->_eval($php_resource);
|
||||
}
|
||||
}
|
||||
|
||||
$function_name = $smarty->_plugins['insert'][$name][0];
|
||||
if (empty($args['assign'])) {
|
||||
$replace = $function_name($args, $smarty);
|
||||
} else {
|
||||
$smarty->assign($args['assign'], $function_name($args, $smarty));
|
||||
$replace = '';
|
||||
}
|
||||
|
||||
$params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
$smarty->_smarty_debug_info[] = array('type' => 'insert',
|
||||
'filename' => 'insert_'.$name,
|
||||
'depth' => $smarty->_inclusion_depth,
|
||||
'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
|
||||
}
|
||||
}
|
||||
|
||||
return $params['results'];
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replace nocache-tags by results of the corresponding non-cacheable
|
||||
* functions and return it
|
||||
*
|
||||
* @param string $compiled_tpl
|
||||
* @param string $cached_source
|
||||
* @return string
|
||||
*/
|
||||
|
||||
function smarty_core_process_compiled_include($params, &$smarty)
|
||||
{
|
||||
$_cache_including = $smarty->_cache_including;
|
||||
$smarty->_cache_including = true;
|
||||
|
||||
$_return = $params['results'];
|
||||
|
||||
foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
|
||||
$smarty->_include($_include_file_path, true);
|
||||
}
|
||||
|
||||
foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
|
||||
$_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
|
||||
array(&$smarty, '_process_compiled_include_callback'),
|
||||
$_return);
|
||||
}
|
||||
$smarty->_cache_including = $_cache_including;
|
||||
return $_return;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* read a cache file, determine if it needs to be
|
||||
* regenerated or not
|
||||
*
|
||||
* @param string $tpl_file
|
||||
* @param string $cache_id
|
||||
* @param string $compile_id
|
||||
* @param string $results
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
// $tpl_file, $cache_id, $compile_id, &$results
|
||||
|
||||
function smarty_core_read_cache_file(&$params, &$smarty)
|
||||
{
|
||||
static $content_cache = array();
|
||||
|
||||
if ($smarty->force_compile) {
|
||||
// force compile enabled, always regenerate
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
|
||||
list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!empty($smarty->cache_handler_func)) {
|
||||
// use cache_handler function
|
||||
call_user_func_array($smarty->cache_handler_func,
|
||||
array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
|
||||
} else {
|
||||
// use local cache file
|
||||
$_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
|
||||
$_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
|
||||
$params['results'] = $smarty->_read_file($_cache_file);
|
||||
}
|
||||
|
||||
if (empty($params['results'])) {
|
||||
// nothing to parse (error?), regenerate cache
|
||||
return false;
|
||||
}
|
||||
|
||||
$_contents = $params['results'];
|
||||
$_info_start = strpos($_contents, "\n") + 1;
|
||||
$_info_len = (int)substr($_contents, 0, $_info_start - 1);
|
||||
$_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
|
||||
$params['results'] = substr($_contents, $_info_start + $_info_len);
|
||||
|
||||
if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
|
||||
// caching by expiration time
|
||||
if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
|
||||
// cache expired, regenerate
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// caching by lifetime
|
||||
if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
|
||||
// cache expired, regenerate
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($smarty->compile_check) {
|
||||
$_params = array('get_source' => false, 'quiet'=>true);
|
||||
foreach (array_keys($_cache_info['template']) as $_template_dep) {
|
||||
$_params['resource_name'] = $_template_dep;
|
||||
if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
|
||||
// template file has changed, regenerate cache
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_cache_info['config'])) {
|
||||
$_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
|
||||
foreach (array_keys($_cache_info['config']) as $_config_dep) {
|
||||
$_params['resource_name'] = $_config_dep;
|
||||
if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
|
||||
// config file has changed, regenerate cache
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
|
||||
|
||||
$smarty->_cache_info = $_cache_info;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* delete an automagically created file by name and id
|
||||
*
|
||||
* @param string $auto_base
|
||||
* @param string $auto_source
|
||||
* @param string $auto_id
|
||||
* @param integer $exp_time
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
|
||||
|
||||
function smarty_core_rm_auto($params, &$smarty)
|
||||
{
|
||||
if (!@is_dir($params['auto_base']))
|
||||
return false;
|
||||
|
||||
if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
|
||||
$_params = array(
|
||||
'dirname' => $params['auto_base'],
|
||||
'level' => 0,
|
||||
'exp_time' => $params['exp_time']
|
||||
);
|
||||
require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
|
||||
$_res = smarty_core_rmdir($_params, $smarty);
|
||||
} else {
|
||||
$_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
|
||||
|
||||
if(isset($params['auto_source'])) {
|
||||
if (isset($params['extensions'])) {
|
||||
$_res = false;
|
||||
foreach ((array)$params['extensions'] as $_extension)
|
||||
$_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
|
||||
} else {
|
||||
$_res = $smarty->_unlink($_tname, $params['exp_time']);
|
||||
}
|
||||
} elseif ($smarty->use_sub_dirs) {
|
||||
$_params = array(
|
||||
'dirname' => $_tname,
|
||||
'level' => 1,
|
||||
'exp_time' => $params['exp_time']
|
||||
);
|
||||
require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
|
||||
$_res = smarty_core_rmdir($_params, $smarty);
|
||||
} else {
|
||||
// remove matching file names
|
||||
$_handle = opendir($params['auto_base']);
|
||||
$_res = true;
|
||||
while (false !== ($_filename = readdir($_handle))) {
|
||||
if($_filename == '.' || $_filename == '..') {
|
||||
continue;
|
||||
} elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
|
||||
$_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_res;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* delete a dir recursively (level=0 -> keep root)
|
||||
* WARNING: no tests, it will try to remove what you tell it!
|
||||
*
|
||||
* @param string $dirname
|
||||
* @param integer $level
|
||||
* @param integer $exp_time
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
// $dirname, $level = 1, $exp_time = null
|
||||
|
||||
function smarty_core_rmdir($params, &$smarty)
|
||||
{
|
||||
if(!isset($params['level'])) { $params['level'] = 1; }
|
||||
if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
|
||||
|
||||
if($_handle = @opendir($params['dirname'])) {
|
||||
|
||||
while (false !== ($_entry = readdir($_handle))) {
|
||||
if ($_entry != '.' && $_entry != '..') {
|
||||
if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
|
||||
$_params = array(
|
||||
'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
|
||||
'level' => $params['level'] + 1,
|
||||
'exp_time' => $params['exp_time']
|
||||
);
|
||||
smarty_core_rmdir($_params, $smarty);
|
||||
}
|
||||
else {
|
||||
$smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($_handle);
|
||||
}
|
||||
|
||||
if ($params['level']) {
|
||||
return @rmdir($params['dirname']);
|
||||
}
|
||||
return (bool)$_handle;
|
||||
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle insert tags
|
||||
*
|
||||
* @param array $args
|
||||
* @return string
|
||||
*/
|
||||
function smarty_core_run_insert_handler($params, &$smarty)
|
||||
{
|
||||
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
$_debug_start_time = smarty_core_get_microtime($_params, $smarty);
|
||||
}
|
||||
|
||||
if ($smarty->caching) {
|
||||
$_arg_string = serialize($params['args']);
|
||||
$_name = $params['args']['name'];
|
||||
if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
|
||||
$smarty->_cache_info['insert_tags'][$_name] = array('insert',
|
||||
$_name,
|
||||
$smarty->_plugins['insert'][$_name][1],
|
||||
$smarty->_plugins['insert'][$_name][2],
|
||||
!empty($params['args']['script']) ? true : false);
|
||||
}
|
||||
return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
|
||||
} else {
|
||||
if (isset($params['args']['script'])) {
|
||||
$_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
|
||||
if(!smarty_core_get_php_resource($_params, $smarty)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($_params['resource_type'] == 'file') {
|
||||
$smarty->_include($_params['php_resource'], true);
|
||||
} else {
|
||||
$smarty->_eval($_params['php_resource']);
|
||||
}
|
||||
unset($params['args']['script']);
|
||||
}
|
||||
|
||||
$_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
|
||||
$_content = $_funcname($params['args'], $smarty);
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
$smarty->_smarty_debug_info[] = array('type' => 'insert',
|
||||
'filename' => 'insert_'.$params['args']['name'],
|
||||
'depth' => $smarty->_inclusion_depth,
|
||||
'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
|
||||
}
|
||||
|
||||
if (!empty($params['args']["assign"])) {
|
||||
$smarty->assign($params['args']["assign"], $_content);
|
||||
} else {
|
||||
return $_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* called for included php files within templates
|
||||
*
|
||||
* @param string $smarty_file
|
||||
* @param string $smarty_assign variable to assign the included template's
|
||||
* output into
|
||||
* @param boolean $smarty_once uses include_once if this is true
|
||||
* @param array $smarty_include_vars associative array of vars from
|
||||
* {include file="blah" var=$var}
|
||||
*/
|
||||
|
||||
// $file, $assign, $once, $_smarty_include_vars
|
||||
|
||||
function smarty_core_smarty_include_php($params, &$smarty)
|
||||
{
|
||||
$_params = array('resource_name' => $params['smarty_file']);
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
|
||||
smarty_core_get_php_resource($_params, $smarty);
|
||||
$_smarty_resource_type = $_params['resource_type'];
|
||||
$_smarty_php_resource = $_params['php_resource'];
|
||||
|
||||
if (!empty($params['smarty_assign'])) {
|
||||
ob_start();
|
||||
if ($_smarty_resource_type == 'file') {
|
||||
$smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
|
||||
} else {
|
||||
$smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
|
||||
}
|
||||
$smarty->assign($params['smarty_assign'], ob_get_contents());
|
||||
ob_end_clean();
|
||||
} else {
|
||||
if ($_smarty_resource_type == 'file') {
|
||||
$smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
|
||||
} else {
|
||||
$smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepend the cache information to the cache file
|
||||
* and write it
|
||||
*
|
||||
* @param string $tpl_file
|
||||
* @param string $cache_id
|
||||
* @param string $compile_id
|
||||
* @param string $results
|
||||
* @return true|null
|
||||
*/
|
||||
|
||||
// $tpl_file, $cache_id, $compile_id, $results
|
||||
|
||||
function smarty_core_write_cache_file($params, &$smarty)
|
||||
{
|
||||
|
||||
// put timestamp in cache header
|
||||
$smarty->_cache_info['timestamp'] = time();
|
||||
if ($smarty->cache_lifetime > -1){
|
||||
// expiration set
|
||||
$smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
|
||||
} else {
|
||||
// cache will never expire
|
||||
$smarty->_cache_info['expires'] = -1;
|
||||
}
|
||||
|
||||
// collapse nocache.../nocache-tags
|
||||
if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
|
||||
// remove everything between every pair of outermost noache.../nocache-tags
|
||||
// and replace it by a single nocache-tag
|
||||
// this new nocache-tag will be replaced by dynamic contents in
|
||||
// smarty_core_process_compiled_includes() on a cache-read
|
||||
|
||||
$match_count = count($match[0]);
|
||||
$results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
|
||||
$level = 0;
|
||||
$j = 0;
|
||||
for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
|
||||
if ($results[$i] == $match[0][$j]) {
|
||||
// nocache tag
|
||||
if ($match[1][$j]) { // closing tag
|
||||
$level--;
|
||||
unset($results[$i]);
|
||||
} else { // opening tag
|
||||
if ($level++ > 0) unset($results[$i]);
|
||||
}
|
||||
$j++;
|
||||
} elseif ($level > 0) {
|
||||
unset($results[$i]);
|
||||
}
|
||||
}
|
||||
$params['results'] = implode('', $results);
|
||||
}
|
||||
$smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
|
||||
|
||||
// prepend the cache header info into cache file
|
||||
$_cache_info = serialize($smarty->_cache_info);
|
||||
$params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
|
||||
|
||||
if (!empty($smarty->cache_handler_func)) {
|
||||
// use cache_handler function
|
||||
call_user_func_array($smarty->cache_handler_func,
|
||||
array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
|
||||
} else {
|
||||
// use local cache file
|
||||
|
||||
if(!@is_writable($smarty->cache_dir)) {
|
||||
// cache_dir not writable, see if it exists
|
||||
if(!@is_dir($smarty->cache_dir)) {
|
||||
$smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
$smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
|
||||
$_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
|
||||
$_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
|
||||
require_once(SMARTY_CORE_DIR . 'core.write_file.php');
|
||||
smarty_core_write_file($_params, $smarty);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extract non-cacheable parts out of compiled template and write it
|
||||
*
|
||||
* @param string $compile_path
|
||||
* @param string $template_compiled
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function smarty_core_write_compiled_include($params, &$smarty)
|
||||
{
|
||||
$_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
|
||||
$_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
|
||||
|
||||
preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
|
||||
$params['compiled_content'], $_match_source, PREG_SET_ORDER);
|
||||
|
||||
// no nocache-parts found: done
|
||||
if (count($_match_source)==0) return;
|
||||
|
||||
// convert the matched php-code to functions
|
||||
$_include_compiled = "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
|
||||
$_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
|
||||
|
||||
$_compile_path = $params['include_file_path'];
|
||||
|
||||
$smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
|
||||
$_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
|
||||
|
||||
$_include_compiled .= $params['plugins_code'];
|
||||
$_include_compiled .= "<?php";
|
||||
|
||||
$this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
|
||||
for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
|
||||
$_match =& $_match_source[$_i];
|
||||
$source = $_match[4];
|
||||
if ($this_varname == '_smarty') {
|
||||
/* rename $this to $_smarty in the sourcecode */
|
||||
$tokens = token_get_all('<?php ' . $_match[4]);
|
||||
|
||||
/* remove trailing <?php */
|
||||
$open_tag = '';
|
||||
while ($tokens) {
|
||||
$token = array_shift($tokens);
|
||||
if (is_array($token)) {
|
||||
$open_tag .= $token[1];
|
||||
} else {
|
||||
$open_tag .= $token;
|
||||
}
|
||||
if ($open_tag == '<?php ') break;
|
||||
}
|
||||
|
||||
for ($i=0, $count = count($tokens); $i < $count; $i++) {
|
||||
if (is_array($tokens[$i])) {
|
||||
if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
|
||||
$tokens[$i] = '$' . $this_varname;
|
||||
} else {
|
||||
$tokens[$i] = $tokens[$i][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
$source = implode('', $tokens);
|
||||
}
|
||||
|
||||
/* add function to compiled include */
|
||||
$_include_compiled .= "
|
||||
function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
|
||||
{
|
||||
$source
|
||||
}
|
||||
|
||||
";
|
||||
}
|
||||
$_include_compiled .= "\n\n?>\n";
|
||||
|
||||
$_params = array('filename' => $_compile_path,
|
||||
'contents' => $_include_compiled, 'create_dirs' => true);
|
||||
|
||||
require_once(SMARTY_CORE_DIR . 'core.write_file.php');
|
||||
smarty_core_write_file($_params, $smarty);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* write the compiled resource
|
||||
*
|
||||
* @param string $compile_path
|
||||
* @param string $compiled_content
|
||||
* @return true
|
||||
*/
|
||||
function smarty_core_write_compiled_resource($params, &$smarty)
|
||||
{
|
||||
if(!@is_writable($smarty->compile_dir)) {
|
||||
// compile_dir not writable, see if it exists
|
||||
if(!@is_dir($smarty->compile_dir)) {
|
||||
$smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
$smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
|
||||
require_once(SMARTY_CORE_DIR . 'core.write_file.php');
|
||||
smarty_core_write_file($_params, $smarty);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* write out a file to disk
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $contents
|
||||
* @param boolean $create_dirs
|
||||
* @return boolean
|
||||
*/
|
||||
function smarty_core_write_file($params, &$smarty)
|
||||
{
|
||||
$_dirname = dirname($params['filename']);
|
||||
|
||||
if ($params['create_dirs']) {
|
||||
$_params = array('dir' => $_dirname);
|
||||
require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
|
||||
smarty_core_create_dir_structure($_params, $smarty);
|
||||
}
|
||||
|
||||
// write to tmp file, then rename it to avoid file locking race condition
|
||||
$_tmp_file = tempnam($_dirname, 'wrt');
|
||||
|
||||
if (!($fd = @fopen($_tmp_file, 'wb'))) {
|
||||
$_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
|
||||
if (!($fd = @fopen($_tmp_file, 'wb'))) {
|
||||
$smarty->trigger_error("problem writing temporary file '$_tmp_file'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($fd, $params['contents']);
|
||||
fclose($fd);
|
||||
|
||||
if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
|
||||
// On platforms and filesystems that cannot overwrite with rename()
|
||||
// delete the file before renaming it -- because windows always suffers
|
||||
// this, it is short-circuited to avoid the initial rename() attempt
|
||||
@unlink($params['filename']);
|
||||
@rename($_tmp_file, $params['filename']);
|
||||
}
|
||||
@chmod($params['filename'], $smarty->_file_perms);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,34 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
* Smarty plugin to format text blocks
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsBlock
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {textformat}{/textformat} block plugin
|
||||
*
|
||||
* Type: block function<br>
|
||||
* Name: textformat<br>
|
||||
* Purpose: format text a certain way with preset styles
|
||||
* or custom wrap/indent settings<br>
|
||||
* @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
|
||||
* (Smarty online manual)
|
||||
* @param array
|
||||
* Params:
|
||||
* <pre>
|
||||
* Params: style: string (email)
|
||||
* indent: integer (0)
|
||||
* wrap: integer (80)
|
||||
* wrap_char string ("\n")
|
||||
* indent_char: string (" ")
|
||||
* wrap_boundary: boolean (true)
|
||||
* - style - string (email)
|
||||
* - indent - integer (0)
|
||||
* - wrap - integer (80)
|
||||
* - wrap_char - string ("\n")
|
||||
* - indent_char - string (" ")
|
||||
* - wrap_boundary - boolean (true)
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param string $content contents of the block
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
* @param boolean &$repeat repeat flag
|
||||
*
|
||||
* @return string content re-formatted
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param string contents of the block
|
||||
* @param Smarty clever simulation of a method
|
||||
* @return string string $content re-formatted
|
||||
*/
|
||||
function smarty_block_textformat($params, $content, &$smarty)
|
||||
function smarty_block_textformat($params, $content, $template, &$repeat)
|
||||
{
|
||||
if (is_null($content)) {
|
||||
return;
|
||||
@@ -42,62 +47,64 @@ function smarty_block_textformat($params, $content, &$smarty)
|
||||
$wrap_char = "\n";
|
||||
$wrap_cut = false;
|
||||
$assign = null;
|
||||
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'style':
|
||||
case 'indent_char':
|
||||
case 'wrap_char':
|
||||
case 'assign':
|
||||
$$_key = (string)$_val;
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'indent':
|
||||
case 'indent_first':
|
||||
case 'wrap':
|
||||
$$_key = (int)$_val;
|
||||
$$_key = (int) $_val;
|
||||
break;
|
||||
|
||||
case 'wrap_cut':
|
||||
$$_key = (bool)$_val;
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
$smarty->trigger_error("textformat: unknown attribute '$_key'");
|
||||
trigger_error("textformat: unknown attribute '$_key'");
|
||||
}
|
||||
}
|
||||
|
||||
if ($style == 'email') {
|
||||
$wrap = 72;
|
||||
}
|
||||
|
||||
// split into paragraphs
|
||||
$_paragraphs = preg_split('![\r\n][\r\n]!',$content);
|
||||
$_output = '';
|
||||
$_paragraphs = preg_split('![\r\n]{2}!', $content);
|
||||
|
||||
for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
|
||||
if ($_paragraphs[$_x] == '') {
|
||||
foreach ($_paragraphs as &$_paragraph) {
|
||||
if (!$_paragraph) {
|
||||
continue;
|
||||
}
|
||||
// convert mult. spaces & special chars to single space
|
||||
$_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
|
||||
$_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph);
|
||||
// indent first line
|
||||
if($indent_first > 0) {
|
||||
$_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
|
||||
if ($indent_first > 0) {
|
||||
$_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
|
||||
}
|
||||
// wordwrap sentences
|
||||
$_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
|
||||
if (Smarty::$_MBSTRING) {
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
|
||||
$_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
||||
} else {
|
||||
$_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
|
||||
}
|
||||
// indent lines
|
||||
if($indent > 0) {
|
||||
$_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
|
||||
if ($indent > 0) {
|
||||
$_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
|
||||
}
|
||||
}
|
||||
$_output = implode($wrap_char . $wrap_char, $_paragraphs);
|
||||
|
||||
return $assign ? $smarty->assign($assign, $_output) : $_output;
|
||||
|
||||
if ($assign) {
|
||||
$template->assign($assign, $_output);
|
||||
} else {
|
||||
return $_output;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {assign} compiler function plugin
|
||||
*
|
||||
* Type: compiler function<br>
|
||||
* Name: assign<br>
|
||||
* Purpose: assign a value to a template variable
|
||||
* @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com> (initial author)
|
||||
* @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
|
||||
* @param string containing var-attribute and value-attribute
|
||||
* @param Smarty_Compiler
|
||||
*/
|
||||
function smarty_compiler_assign($tag_attrs, &$compiler)
|
||||
{
|
||||
$_params = $compiler->_parse_attrs($tag_attrs);
|
||||
|
||||
if (!isset($_params['var'])) {
|
||||
$compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($_params['value'])) {
|
||||
$compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
return "\$this->assign({$_params['var']}, {$_params['value']});";
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {assign_debug_info} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: assign_debug_info<br>
|
||||
* Purpose: assign debug info to the template<br>
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
|
||||
* {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
|
||||
* @param Smarty
|
||||
*/
|
||||
function smarty_function_assign_debug_info($params, &$smarty)
|
||||
{
|
||||
$assigned_vars = $smarty->_tpl_vars;
|
||||
ksort($assigned_vars);
|
||||
if (@is_array($smarty->_config[0])) {
|
||||
$config_vars = $smarty->_config[0];
|
||||
ksort($config_vars);
|
||||
$smarty->assign("_debug_config_keys", array_keys($config_vars));
|
||||
$smarty->assign("_debug_config_vals", array_values($config_vars));
|
||||
}
|
||||
|
||||
$included_templates = $smarty->_smarty_debug_info;
|
||||
|
||||
$smarty->assign("_debug_keys", array_keys($assigned_vars));
|
||||
$smarty->assign("_debug_vals", array_values($assigned_vars));
|
||||
|
||||
$smarty->assign("_debug_tpls", $included_templates);
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,142 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {config_load} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: config_load<br>
|
||||
* Purpose: load config file vars
|
||||
* @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
|
||||
* @param array Format:
|
||||
* <pre>
|
||||
* array('file' => required config file name,
|
||||
* 'section' => optional config file section to load
|
||||
* 'scope' => local/parent/global
|
||||
* 'global' => overrides scope, setting to parent if true)
|
||||
* </pre>
|
||||
* @param Smarty
|
||||
*/
|
||||
function smarty_function_config_load($params, &$smarty)
|
||||
{
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
$_debug_start_time = smarty_core_get_microtime($_params, $smarty);
|
||||
}
|
||||
|
||||
$_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
|
||||
$_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
|
||||
$_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
|
||||
$_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
|
||||
|
||||
if (!isset($_file) || strlen($_file) == 0) {
|
||||
$smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
if (isset($_scope)) {
|
||||
if ($_scope != 'local' &&
|
||||
$_scope != 'parent' &&
|
||||
$_scope != 'global') {
|
||||
$smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
|
||||
}
|
||||
} else {
|
||||
if ($_global) {
|
||||
$_scope = 'parent';
|
||||
} else {
|
||||
$_scope = 'local';
|
||||
}
|
||||
}
|
||||
|
||||
$_params = array('resource_name' => $_file,
|
||||
'resource_base_path' => $smarty->config_dir,
|
||||
'get_source' => false);
|
||||
$smarty->_parse_resource_name($_params);
|
||||
$_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
|
||||
if (isset($_section))
|
||||
$_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
|
||||
else
|
||||
$_compile_file = $smarty->_get_compile_path($_file_path);
|
||||
|
||||
if($smarty->force_compile || !file_exists($_compile_file)) {
|
||||
$_compile = true;
|
||||
} elseif ($smarty->compile_check) {
|
||||
$_params = array('resource_name' => $_file,
|
||||
'resource_base_path' => $smarty->config_dir,
|
||||
'get_source' => false);
|
||||
$_compile = $smarty->_fetch_resource_info($_params) &&
|
||||
$_params['resource_timestamp'] > filemtime($_compile_file);
|
||||
} else {
|
||||
$_compile = false;
|
||||
}
|
||||
|
||||
if($_compile) {
|
||||
// compile config file
|
||||
if(!is_object($smarty->_conf_obj)) {
|
||||
require_once SMARTY_DIR . $smarty->config_class . '.class.php';
|
||||
$smarty->_conf_obj = new $smarty->config_class();
|
||||
$smarty->_conf_obj->overwrite = $smarty->config_overwrite;
|
||||
$smarty->_conf_obj->booleanize = $smarty->config_booleanize;
|
||||
$smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
|
||||
$smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
|
||||
}
|
||||
|
||||
$_params = array('resource_name' => $_file,
|
||||
'resource_base_path' => $smarty->config_dir,
|
||||
$_params['get_source'] = true);
|
||||
if (!$smarty->_fetch_resource_info($_params)) {
|
||||
return;
|
||||
}
|
||||
$smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
|
||||
$_config_vars = array_merge($smarty->_conf_obj->get($_file),
|
||||
$smarty->_conf_obj->get($_file, $_section));
|
||||
if(function_exists('var_export')) {
|
||||
$_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
|
||||
} else {
|
||||
$_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
|
||||
}
|
||||
$_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
|
||||
require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
|
||||
smarty_core_write_compiled_resource($_params, $smarty);
|
||||
} else {
|
||||
include($_compile_file);
|
||||
}
|
||||
|
||||
if ($smarty->caching) {
|
||||
$smarty->_cache_info['config'][$_file] = true;
|
||||
}
|
||||
|
||||
$smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
|
||||
$smarty->_config[0]['files'][$_file] = true;
|
||||
|
||||
if ($_scope == 'parent') {
|
||||
$smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
|
||||
$smarty->_config[1]['files'][$_file] = true;
|
||||
} else if ($_scope == 'global') {
|
||||
for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
|
||||
$smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
|
||||
$smarty->_config[$i]['files'][$_file] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($smarty->debugging) {
|
||||
$_params = array();
|
||||
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
|
||||
$smarty->_smarty_debug_info[] = array('type' => 'config',
|
||||
'filename' => $_file.' ['.$_section.'] '.$_scope,
|
||||
'depth' => $smarty->_inclusion_depth,
|
||||
'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,41 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {counter} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: counter<br>
|
||||
* Purpose: print out a counter value
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
|
||||
* (Smarty online manual)
|
||||
* @param array parameters
|
||||
* @param Smarty
|
||||
* @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_counter($params, &$smarty)
|
||||
function smarty_function_counter($params, $template)
|
||||
{
|
||||
static $counters = array();
|
||||
|
||||
$name = (isset($params['name'])) ? $params['name'] : 'default';
|
||||
if (!isset($counters[$name])) {
|
||||
$counters[$name] = array(
|
||||
'start'=>1,
|
||||
'skip'=>1,
|
||||
'direction'=>'up',
|
||||
'count'=>1
|
||||
);
|
||||
'start' => 1,
|
||||
'skip' => 1,
|
||||
'direction' => 'up',
|
||||
'count' => 1
|
||||
);
|
||||
}
|
||||
$counter =& $counters[$name];
|
||||
|
||||
if (isset($params['start'])) {
|
||||
$counter['start'] = $counter['count'] = (int)$params['start'];
|
||||
$counter['start'] = $counter['count'] = (int) $params['start'];
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
@@ -43,11 +45,11 @@ function smarty_function_counter($params, &$smarty)
|
||||
}
|
||||
|
||||
if (isset($counter['assign'])) {
|
||||
$smarty->assign($counter['assign'], $counter['count']);
|
||||
$template->assign($counter['assign'], $counter['count']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($params['print'])) {
|
||||
$print = (bool)$params['print'];
|
||||
$print = (bool) $params['print'];
|
||||
} else {
|
||||
$print = empty($counter['assign']);
|
||||
}
|
||||
@@ -61,20 +63,16 @@ function smarty_function_counter($params, &$smarty)
|
||||
if (isset($params['skip'])) {
|
||||
$counter['skip'] = $params['skip'];
|
||||
}
|
||||
|
||||
|
||||
if (isset($params['direction'])) {
|
||||
$counter['direction'] = $params['direction'];
|
||||
}
|
||||
|
||||
if ($counter['direction'] == "down")
|
||||
if ($counter['direction'] == "down") {
|
||||
$counter['count'] -= $counter['skip'];
|
||||
else
|
||||
} else {
|
||||
$counter['count'] += $counter['skip'];
|
||||
|
||||
}
|
||||
|
||||
return $retval;
|
||||
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,102 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Smarty {cycle} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: cycle<br>
|
||||
* Date: May 3, 2002<br>
|
||||
* Purpose: cycle through given values<br>
|
||||
* Input:
|
||||
* - name = name of cycle (optional)
|
||||
* - values = comma separated list of values to cycle,
|
||||
* or an array of values to cycle
|
||||
* (this can be left out for subsequent calls)
|
||||
* - reset = boolean - resets given var to true
|
||||
* - print = boolean - print var or not. default is true
|
||||
* - advance = boolean - whether or not to advance the cycle
|
||||
* - delimiter = the value delimiter, default is ","
|
||||
* - assign = boolean, assigns to template var instead of
|
||||
* printed.
|
||||
*
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name - name of cycle (optional)
|
||||
* - values - comma separated list of values to cycle, or an array of values to cycle
|
||||
* (this can be left out for subsequent calls)
|
||||
* - reset - boolean - resets given var to true
|
||||
* - print - boolean - print var or not. default is true
|
||||
* - advance - boolean - whether or not to advance the cycle
|
||||
* - delimiter - the value delimiter, default is ","
|
||||
* - assign - boolean, assigns to template var instead of printed.
|
||||
* </pre>
|
||||
* Examples:<br>
|
||||
* <pre>
|
||||
* {cycle values="#eeeeee,#d0d0d0d"}
|
||||
* {cycle name=row values="one,two,three" reset=true}
|
||||
* {cycle name=row}
|
||||
* </pre>
|
||||
* @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credit to Mark Priatel <mpriatel@rogers.com>
|
||||
* @author credit to Gerard <gerard@interfold.com>
|
||||
* @author credit to Jason Sweat <jsweat_php@yahoo.com>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credit to Mark Priatel <mpriatel@rogers.com>
|
||||
* @author credit to Gerard <gerard@interfold.com>
|
||||
* @author credit to Jason Sweat <jsweat_php@yahoo.com>
|
||||
* @version 1.3
|
||||
* @param array
|
||||
* @param Smarty
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_cycle($params, &$smarty)
|
||||
|
||||
function smarty_function_cycle($params, $template)
|
||||
{
|
||||
static $cycle_vars;
|
||||
|
||||
|
||||
$name = (empty($params['name'])) ? 'default' : $params['name'];
|
||||
$print = (isset($params['print'])) ? (bool)$params['print'] : true;
|
||||
$advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
|
||||
$reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
|
||||
|
||||
if (!in_array('values', array_keys($params))) {
|
||||
if(!isset($cycle_vars[$name]['values'])) {
|
||||
$smarty->trigger_error("cycle: missing 'values' parameter");
|
||||
$print = (isset($params['print'])) ? (bool) $params['print'] : true;
|
||||
$advance = (isset($params['advance'])) ? (bool) $params['advance'] : true;
|
||||
$reset = (isset($params['reset'])) ? (bool) $params['reset'] : false;
|
||||
|
||||
if (!isset($params['values'])) {
|
||||
if (!isset($cycle_vars[$name]['values'])) {
|
||||
trigger_error("cycle: missing 'values' parameter");
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(isset($cycle_vars[$name]['values'])
|
||||
&& $cycle_vars[$name]['values'] != $params['values'] ) {
|
||||
if (isset($cycle_vars[$name]['values'])
|
||||
&& $cycle_vars[$name]['values'] != $params['values']
|
||||
) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
}
|
||||
$cycle_vars[$name]['values'] = $params['values'];
|
||||
}
|
||||
|
||||
$cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
|
||||
|
||||
if(is_array($cycle_vars[$name]['values'])) {
|
||||
if (isset($params['delimiter'])) {
|
||||
$cycle_vars[$name]['delimiter'] = $params['delimiter'];
|
||||
} elseif (!isset($cycle_vars[$name]['delimiter'])) {
|
||||
$cycle_vars[$name]['delimiter'] = ',';
|
||||
}
|
||||
|
||||
if (is_array($cycle_vars[$name]['values'])) {
|
||||
$cycle_array = $cycle_vars[$name]['values'];
|
||||
} else {
|
||||
$cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
|
||||
$cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']);
|
||||
}
|
||||
|
||||
if(!isset($cycle_vars[$name]['index']) || $reset ) {
|
||||
|
||||
if (!isset($cycle_vars[$name]['index']) || $reset) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (isset($params['assign'])) {
|
||||
$print = false;
|
||||
$smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
|
||||
$template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
|
||||
}
|
||||
|
||||
if($print) {
|
||||
|
||||
if ($print) {
|
||||
$retval = $cycle_array[$cycle_vars[$name]['index']];
|
||||
} else {
|
||||
$retval = null;
|
||||
}
|
||||
|
||||
if($advance) {
|
||||
if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
|
||||
if ($advance) {
|
||||
if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) {
|
||||
$cycle_vars[$name]['index'] = 0;
|
||||
} else {
|
||||
$cycle_vars[$name]['index']++;
|
||||
$cycle_vars[$name]['index'] ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {debug} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: debug<br>
|
||||
* Date: July 1, 2002<br>
|
||||
* Purpose: popup debug window
|
||||
* @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string output from {@link Smarty::_generate_debug_output()}
|
||||
*/
|
||||
function smarty_function_debug($params, &$smarty)
|
||||
{
|
||||
if (isset($params['output'])) {
|
||||
$smarty->assign('_smarty_debug_output', $params['output']);
|
||||
}
|
||||
require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
|
||||
return smarty_core_display_debug_console(null, $smarty);
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {eval} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: eval<br>
|
||||
* Purpose: evaluate a template variable as a template<br>
|
||||
* @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
*/
|
||||
function smarty_function_eval($params, &$smarty)
|
||||
{
|
||||
|
||||
if (!isset($params['var'])) {
|
||||
$smarty->trigger_error("eval: missing 'var' parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
if($params['var'] == '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
|
||||
|
||||
ob_start();
|
||||
$smarty->_eval('?>' . $_var_compiled);
|
||||
$_contents = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$smarty->assign($params['assign'], $_contents);
|
||||
} else {
|
||||
return $_contents;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,221 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {fetch} plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: fetch<br>
|
||||
* Purpose: fetch file, web or ftp data and display results
|
||||
* @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string|null if the assign parameter is passed, Smarty assigns the
|
||||
* result to a template variable
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
|
||||
*/
|
||||
function smarty_function_fetch($params, &$smarty)
|
||||
function smarty_function_fetch($params, $template)
|
||||
{
|
||||
if (empty($params['file'])) {
|
||||
$smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
|
||||
trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$content = '';
|
||||
if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
|
||||
$_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
|
||||
require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
|
||||
if(!smarty_core_is_secure($_params, $smarty)) {
|
||||
$smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch the file
|
||||
if($fp = @fopen($params['file'],'r')) {
|
||||
while(!feof($fp)) {
|
||||
$content .= fgets ($fp,4096);
|
||||
// strip file protocol
|
||||
if (stripos($params['file'], 'file://') === 0) {
|
||||
$params['file'] = substr($params['file'], 7);
|
||||
}
|
||||
|
||||
$protocol = strpos($params['file'], '://');
|
||||
if ($protocol !== false) {
|
||||
$protocol = strtolower(substr($params['file'], 0, $protocol));
|
||||
}
|
||||
|
||||
if (isset($template->smarty->security_policy)) {
|
||||
if ($protocol) {
|
||||
// remote resource (or php stream, …)
|
||||
if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
|
||||
return;
|
||||
}
|
||||
fclose($fp);
|
||||
} else {
|
||||
$smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
|
||||
// local file
|
||||
if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
if ($protocol == 'http') {
|
||||
// http fetch
|
||||
if ($uri_parts = parse_url($params['file'])) {
|
||||
// set defaults
|
||||
$host = $server_name = $uri_parts['host'];
|
||||
$timeout = 30;
|
||||
$accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
|
||||
$agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION;
|
||||
$referer = "";
|
||||
$uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
|
||||
$uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
|
||||
$_is_proxy = false;
|
||||
if (empty($uri_parts['port'])) {
|
||||
$port = 80;
|
||||
} else {
|
||||
$port = $uri_parts['port'];
|
||||
}
|
||||
if (!empty($uri_parts['user'])) {
|
||||
$user = $uri_parts['user'];
|
||||
}
|
||||
if (!empty($uri_parts['pass'])) {
|
||||
$pass = $uri_parts['pass'];
|
||||
}
|
||||
// loop through parameters, setup headers
|
||||
foreach ($params as $param_key => $param_value) {
|
||||
switch ($param_key) {
|
||||
case "file":
|
||||
case "assign":
|
||||
case "assign_headers":
|
||||
break;
|
||||
case "user":
|
||||
if (!empty($param_value)) {
|
||||
$user = $param_value;
|
||||
}
|
||||
break;
|
||||
case "pass":
|
||||
if (!empty($param_value)) {
|
||||
$pass = $param_value;
|
||||
}
|
||||
break;
|
||||
case "accept":
|
||||
if (!empty($param_value)) {
|
||||
$accept = $param_value;
|
||||
}
|
||||
break;
|
||||
case "header":
|
||||
if (!empty($param_value)) {
|
||||
if (!preg_match('![\w\d-]+: .+!', $param_value)) {
|
||||
trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
$extra_headers[] = $param_value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "proxy_host":
|
||||
if (!empty($param_value)) {
|
||||
$proxy_host = $param_value;
|
||||
}
|
||||
break;
|
||||
case "proxy_port":
|
||||
if (!preg_match('!\D!', $param_value)) {
|
||||
$proxy_port = (int) $param_value;
|
||||
} else {
|
||||
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "agent":
|
||||
if (!empty($param_value)) {
|
||||
$agent = $param_value;
|
||||
}
|
||||
break;
|
||||
case "referer":
|
||||
if (!empty($param_value)) {
|
||||
$referer = $param_value;
|
||||
}
|
||||
break;
|
||||
case "timeout":
|
||||
if (!preg_match('!\D!', $param_value)) {
|
||||
$timeout = (int) $param_value;
|
||||
} else {
|
||||
trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!empty($proxy_host) && !empty($proxy_port)) {
|
||||
$_is_proxy = true;
|
||||
$fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout);
|
||||
} else {
|
||||
$fp = fsockopen($server_name, $port, $errno, $errstr, $timeout);
|
||||
}
|
||||
|
||||
if (!$fp) {
|
||||
trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
if ($_is_proxy) {
|
||||
fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
|
||||
} else {
|
||||
fputs($fp, "GET $uri HTTP/1.0\r\n");
|
||||
}
|
||||
if (!empty($host)) {
|
||||
fputs($fp, "Host: $host\r\n");
|
||||
}
|
||||
if (!empty($accept)) {
|
||||
fputs($fp, "Accept: $accept\r\n");
|
||||
}
|
||||
if (!empty($agent)) {
|
||||
fputs($fp, "User-Agent: $agent\r\n");
|
||||
}
|
||||
if (!empty($referer)) {
|
||||
fputs($fp, "Referer: $referer\r\n");
|
||||
}
|
||||
if (isset($extra_headers) && is_array($extra_headers)) {
|
||||
foreach ($extra_headers as $curr_header) {
|
||||
fputs($fp, $curr_header . "\r\n");
|
||||
}
|
||||
}
|
||||
if (!empty($user) && !empty($pass)) {
|
||||
fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n");
|
||||
}
|
||||
|
||||
fputs($fp, "\r\n");
|
||||
while (!feof($fp)) {
|
||||
$content .= fgets($fp, 4096);
|
||||
}
|
||||
fclose($fp);
|
||||
$csplit = preg_split("!\r\n\r\n!", $content, 2);
|
||||
|
||||
$content = $csplit[1];
|
||||
|
||||
if (!empty($params['assign_headers'])) {
|
||||
$template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// not a local file
|
||||
if(preg_match('!^http://!i',$params['file'])) {
|
||||
// http fetch
|
||||
if($uri_parts = parse_url($params['file'])) {
|
||||
// set defaults
|
||||
$host = $server_name = $uri_parts['host'];
|
||||
$timeout = 30;
|
||||
$accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
|
||||
$agent = "Smarty Template Engine ".$smarty->_version;
|
||||
$referer = "";
|
||||
$uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
|
||||
$uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
|
||||
$_is_proxy = false;
|
||||
if(empty($uri_parts['port'])) {
|
||||
$port = 80;
|
||||
} else {
|
||||
$port = $uri_parts['port'];
|
||||
}
|
||||
if(!empty($uri_parts['user'])) {
|
||||
$user = $uri_parts['user'];
|
||||
}
|
||||
if(!empty($uri_parts['pass'])) {
|
||||
$pass = $uri_parts['pass'];
|
||||
}
|
||||
// loop through parameters, setup headers
|
||||
foreach($params as $param_key => $param_value) {
|
||||
switch($param_key) {
|
||||
case "file":
|
||||
case "assign":
|
||||
case "assign_headers":
|
||||
break;
|
||||
case "user":
|
||||
if(!empty($param_value)) {
|
||||
$user = $param_value;
|
||||
}
|
||||
break;
|
||||
case "pass":
|
||||
if(!empty($param_value)) {
|
||||
$pass = $param_value;
|
||||
}
|
||||
break;
|
||||
case "accept":
|
||||
if(!empty($param_value)) {
|
||||
$accept = $param_value;
|
||||
}
|
||||
break;
|
||||
case "header":
|
||||
if(!empty($param_value)) {
|
||||
if(!preg_match('![\w\d-]+: .+!',$param_value)) {
|
||||
$smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
|
||||
return;
|
||||
} else {
|
||||
$extra_headers[] = $param_value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "proxy_host":
|
||||
if(!empty($param_value)) {
|
||||
$proxy_host = $param_value;
|
||||
}
|
||||
break;
|
||||
case "proxy_port":
|
||||
if(!preg_match('!\D!', $param_value)) {
|
||||
$proxy_port = (int) $param_value;
|
||||
} else {
|
||||
$smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "agent":
|
||||
if(!empty($param_value)) {
|
||||
$agent = $param_value;
|
||||
}
|
||||
break;
|
||||
case "referer":
|
||||
if(!empty($param_value)) {
|
||||
$referer = $param_value;
|
||||
}
|
||||
break;
|
||||
case "timeout":
|
||||
if(!preg_match('!\D!', $param_value)) {
|
||||
$timeout = (int) $param_value;
|
||||
} else {
|
||||
$smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!empty($proxy_host) && !empty($proxy_port)) {
|
||||
$_is_proxy = true;
|
||||
$fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
|
||||
} else {
|
||||
$fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
|
||||
}
|
||||
|
||||
if(!$fp) {
|
||||
$smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
|
||||
return;
|
||||
} else {
|
||||
if($_is_proxy) {
|
||||
fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
|
||||
} else {
|
||||
fputs($fp, "GET $uri HTTP/1.0\r\n");
|
||||
}
|
||||
if(!empty($host)) {
|
||||
fputs($fp, "Host: $host\r\n");
|
||||
}
|
||||
if(!empty($accept)) {
|
||||
fputs($fp, "Accept: $accept\r\n");
|
||||
}
|
||||
if(!empty($agent)) {
|
||||
fputs($fp, "User-Agent: $agent\r\n");
|
||||
}
|
||||
if(!empty($referer)) {
|
||||
fputs($fp, "Referer: $referer\r\n");
|
||||
}
|
||||
if(isset($extra_headers) && is_array($extra_headers)) {
|
||||
foreach($extra_headers as $curr_header) {
|
||||
fputs($fp, $curr_header."\r\n");
|
||||
}
|
||||
}
|
||||
if(!empty($user) && !empty($pass)) {
|
||||
fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
|
||||
}
|
||||
|
||||
fputs($fp, "\r\n");
|
||||
while(!feof($fp)) {
|
||||
$content .= fgets($fp,4096);
|
||||
}
|
||||
fclose($fp);
|
||||
$csplit = split("\r\n\r\n",$content,2);
|
||||
|
||||
$content = $csplit[1];
|
||||
|
||||
if(!empty($params['assign_headers'])) {
|
||||
$smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// ftp fetch
|
||||
if($fp = @fopen($params['file'],'r')) {
|
||||
while(!feof($fp)) {
|
||||
$content .= fgets ($fp,4096);
|
||||
}
|
||||
fclose($fp);
|
||||
} else {
|
||||
$smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
|
||||
return;
|
||||
}
|
||||
$content = @file_get_contents($params['file']);
|
||||
if ($content === false) {
|
||||
throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$smarty->assign($params['assign'],$content);
|
||||
$template->assign($params['assign'], $content);
|
||||
} else {
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,143 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {html_checkboxes} function plugin
|
||||
*
|
||||
* File: function.html_checkboxes.php<br>
|
||||
* Type: function<br>
|
||||
* Name: html_checkboxes<br>
|
||||
* Date: 24.Feb.2003<br>
|
||||
* Purpose: Prints out a list of checkbox input types<br>
|
||||
* Input:<br>
|
||||
* - name (optional) - string default "checkbox"
|
||||
* - values (required) - array
|
||||
* - options (optional) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each checkbox
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {html_checkboxes values=$ids output=$names}
|
||||
* {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
|
||||
* {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
|
||||
* </pre>
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
|
||||
* (Smarty online manual)
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "checkbox"
|
||||
* - values (required) - array
|
||||
* - options (optional) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each checkbox
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* - escape (optional) - escape the content (not value), defaults to true
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
|
||||
* (Smarty online manual)
|
||||
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
* @param array
|
||||
* @param Smarty
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param object $template template object
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_checkboxes($params, &$smarty)
|
||||
function smarty_function_html_checkboxes($params, $template)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = 'checkbox';
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = null;
|
||||
$selected = array();
|
||||
$separator = '';
|
||||
$escape = true;
|
||||
$labels = true;
|
||||
$label_ids = false;
|
||||
$output = null;
|
||||
|
||||
$extra = '';
|
||||
|
||||
foreach($params as $_key => $_val) {
|
||||
switch($_key) {
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
case 'separator':
|
||||
$$_key = $_val;
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'escape':
|
||||
case 'labels':
|
||||
$$_key = (bool)$_val;
|
||||
case 'label_ids':
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
$$_key = (array)$_val;
|
||||
$$_key = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array)$_val);
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'checked':
|
||||
case 'selected':
|
||||
$selected = array_map('strval', array_values((array)$_val));
|
||||
if (is_array($_val)) {
|
||||
$selected = array();
|
||||
foreach ($_val as $_sel) {
|
||||
if (is_object($_sel)) {
|
||||
if (method_exists($_sel, "__toString")) {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
|
||||
} else {
|
||||
trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel);
|
||||
}
|
||||
$selected[$_sel] = true;
|
||||
}
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'checkboxes':
|
||||
$smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array)$_val;
|
||||
trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'assign':
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if(!is_array($_val)) {
|
||||
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
$smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values))
|
||||
return ''; /* raise error here? */
|
||||
if (!isset($options) && !isset($values)) {
|
||||
return '';
|
||||
} /* raise error here? */
|
||||
|
||||
settype($selected, 'array');
|
||||
$_html_result = array();
|
||||
|
||||
if (isset($options)) {
|
||||
|
||||
foreach ($options as $_key=>$_val)
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
|
||||
|
||||
|
||||
} else {
|
||||
foreach ($values as $_i=>$_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!empty($params['assign'])) {
|
||||
$smarty->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n",$_html_result);
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$template->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n", $_html_result);
|
||||
}
|
||||
}
|
||||
|
||||
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
|
||||
function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true)
|
||||
{
|
||||
$_output = '';
|
||||
if ($labels) $_output .= '<label>';
|
||||
$_output .= '<input type="checkbox" name="'
|
||||
. smarty_function_escape_special_chars($name) . '[]" value="'
|
||||
. smarty_function_escape_special_chars($value) . '"';
|
||||
|
||||
if (in_array((string)$value, $selected)) {
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = (string) $value->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
if (is_object($output)) {
|
||||
if (method_exists($output, "__toString")) {
|
||||
$output = (string) $output->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$output = (string) $output;
|
||||
}
|
||||
|
||||
if ($labels) {
|
||||
if ($label_ids) {
|
||||
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
|
||||
$_output .= '<label for="' . $_id . '">';
|
||||
} else {
|
||||
$_output .= '<label>';
|
||||
}
|
||||
}
|
||||
|
||||
$name = smarty_function_escape_special_chars($name);
|
||||
$value = smarty_function_escape_special_chars($value);
|
||||
if ($escape) {
|
||||
$output = smarty_function_escape_special_chars($output);
|
||||
}
|
||||
|
||||
$_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
|
||||
|
||||
if ($labels && $label_ids) {
|
||||
$_output .= ' id="' . $_id . '"';
|
||||
}
|
||||
|
||||
if (is_array($selected)) {
|
||||
if (isset($selected[$value])) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
} elseif ($value === $selected) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
|
||||
$_output .= $extra . ' />' . $output;
|
||||
if ($labels) $_output .= '</label>';
|
||||
$_output .= $separator;
|
||||
if ($labels) {
|
||||
$_output .= '</label>';
|
||||
}
|
||||
|
||||
$_output .= $separator;
|
||||
|
||||
return $_output;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,43 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {html_image} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: html_image<br>
|
||||
* Date: Feb 24, 2003<br>
|
||||
* Purpose: format HTML tags for the image<br>
|
||||
* Input:<br>
|
||||
* - file = file (and path) of image (required)
|
||||
* - height = image height (optional, default actual height)
|
||||
* - width = image width (optional, default actual width)
|
||||
* - basedir = base directory for absolute paths, default
|
||||
* is environment variable DOCUMENT_ROOT
|
||||
* - path_prefix = prefix for path output (optional, default empty)
|
||||
* Examples: {html_image file="/images/masthead.gif"}<br>
|
||||
* Output: <img src="/images/masthead.gif" width=400 height=23><br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - file - (required) - file (and path) of image
|
||||
* - height - (optional) - image height (default actual height)
|
||||
* - width - (optional) - image width (default actual width)
|
||||
* - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
|
||||
* - path_prefix - prefix for path output (optional, default empty)
|
||||
* </pre>
|
||||
*
|
||||
* Examples: {html_image file="/images/masthead.gif"}
|
||||
* Output: <img src="/images/masthead.gif" width=400 height=23>
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credits to Duda <duda@big.hu> - wrote first image function
|
||||
* in repository, helped with lots of functionality
|
||||
* @version 1.0
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credits to Duda <duda@big.hu>
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @throws SmartyException
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_image($params, &$smarty)
|
||||
function smarty_function_html_image($params, $template)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
|
||||
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$alt = '';
|
||||
$file = '';
|
||||
$height = '';
|
||||
@@ -46,10 +48,9 @@ function smarty_function_html_image($params, &$smarty)
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
$path_prefix = '';
|
||||
$server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
|
||||
$basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
|
||||
foreach($params as $_key => $_val) {
|
||||
switch($_key) {
|
||||
$basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'file':
|
||||
case 'height':
|
||||
case 'width':
|
||||
@@ -60,10 +61,10 @@ function smarty_function_html_image($params, &$smarty)
|
||||
break;
|
||||
|
||||
case 'alt':
|
||||
if(!is_array($_val)) {
|
||||
if (!is_array($_val)) {
|
||||
$$_key = smarty_function_escape_special_chars($_val);
|
||||
} else {
|
||||
$smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -74,69 +75,89 @@ function smarty_function_html_image($params, &$smarty)
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!is_array($_val)) {
|
||||
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
$smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($file)) {
|
||||
$smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
|
||||
trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (substr($file,0,1) == '/') {
|
||||
if ($file[0] == '/') {
|
||||
$_image_path = $basedir . $file;
|
||||
} else {
|
||||
$_image_path = $file;
|
||||
}
|
||||
|
||||
if(!isset($params['width']) || !isset($params['height'])) {
|
||||
if(!$_image_data = @getimagesize($_image_path)) {
|
||||
if(!file_exists($_image_path)) {
|
||||
$smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
|
||||
|
||||
// strip file protocol
|
||||
if (stripos($params['file'], 'file://') === 0) {
|
||||
$params['file'] = substr($params['file'], 7);
|
||||
}
|
||||
|
||||
$protocol = strpos($params['file'], '://');
|
||||
if ($protocol !== false) {
|
||||
$protocol = strtolower(substr($params['file'], 0, $protocol));
|
||||
}
|
||||
|
||||
if (isset($template->smarty->security_policy)) {
|
||||
if ($protocol) {
|
||||
// remote resource (or php stream, …)
|
||||
if (!$template->smarty->security_policy->isTrustedUri($params['file'])) {
|
||||
return;
|
||||
} else if(!is_readable($_image_path)) {
|
||||
$smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
|
||||
return;
|
||||
} else {
|
||||
$smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
// local file
|
||||
if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($smarty->security &&
|
||||
($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
|
||||
(require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
|
||||
(!smarty_core_is_secure($_params, $smarty)) ) {
|
||||
$smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if(!isset($params['width'])) {
|
||||
$width = $_image_data[0];
|
||||
}
|
||||
if(!isset($params['height'])) {
|
||||
$height = $_image_data[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(isset($params['dpi'])) {
|
||||
if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
|
||||
if (!isset($params['width']) || !isset($params['height'])) {
|
||||
// FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
|
||||
if (!$_image_data = @getimagesize($_image_path)) {
|
||||
if (!file_exists($_image_path)) {
|
||||
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} elseif (!is_readable($_image_path)) {
|
||||
trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
} else {
|
||||
trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($params['width'])) {
|
||||
$width = $_image_data[0];
|
||||
}
|
||||
if (!isset($params['height'])) {
|
||||
$height = $_image_data[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($params['dpi'])) {
|
||||
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) {
|
||||
// FIXME: (rodneyrehm) wrong dpi assumption
|
||||
// don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
|
||||
$dpi_default = 72;
|
||||
} else {
|
||||
$dpi_default = 96;
|
||||
}
|
||||
$_resize = $dpi_default/$params['dpi'];
|
||||
$_resize = $dpi_default / $params['dpi'];
|
||||
$width = round($width * $_resize);
|
||||
$height = round($height * $_resize);
|
||||
}
|
||||
|
||||
return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
|
||||
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,122 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {html_options} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: html_options<br>
|
||||
* Input:<br>
|
||||
* - name (optional) - string default "select"
|
||||
* - values (required if no options supplied) - array
|
||||
* - options (required if no values supplied) - associative array
|
||||
* - selected (optional) - string default not set
|
||||
* - output (required if not options supplied) - array
|
||||
* Purpose: Prints the list of <option> tags generated from
|
||||
* the passed parameters
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* the passed parameters<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "select"
|
||||
* - values (required) - if no options supplied) - array
|
||||
* - options (required) - if no values supplied) - associative array
|
||||
* - selected (optional) - string default not set
|
||||
* - output (required) - if not options supplied) - array
|
||||
* - id (optional) - string default not set
|
||||
* - class (optional) - string default not set
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_options($params, &$smarty)
|
||||
function smarty_function_html_options($params)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
|
||||
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = null;
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = array();
|
||||
$selected = null;
|
||||
$output = null;
|
||||
|
||||
$id = null;
|
||||
$class = null;
|
||||
|
||||
$extra = '';
|
||||
|
||||
foreach($params as $_key => $_val) {
|
||||
switch($_key) {
|
||||
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
$$_key = (string)$_val;
|
||||
case 'class':
|
||||
case 'id':
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
|
||||
case 'options':
|
||||
$$_key = (array)$_val;
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array)$_val);
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'selected':
|
||||
$$_key = array_map('strval', array_values((array)$_val));
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!is_array($_val)) {
|
||||
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
|
||||
if (is_array($_val)) {
|
||||
$selected = array();
|
||||
foreach ($_val as $_sel) {
|
||||
if (is_object($_sel)) {
|
||||
if (method_exists($_sel, "__toString")) {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$_sel = smarty_function_escape_special_chars((string) $_sel);
|
||||
}
|
||||
$selected[$_sel] = true;
|
||||
}
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
$selected = smarty_function_escape_special_chars((string) $_val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values))
|
||||
return ''; /* raise error here? */
|
||||
if (!isset($options) && !isset($values)) {
|
||||
/* raise error here? */
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$_html_result = '';
|
||||
$_idx = 0;
|
||||
|
||||
if (isset($options)) {
|
||||
|
||||
foreach ($options as $_key=>$_val)
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
|
||||
|
||||
} else {
|
||||
|
||||
foreach ($values as $_i=>$_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!empty($name)) {
|
||||
$_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
|
||||
}
|
||||
|
||||
return $_html_result;
|
||||
|
||||
}
|
||||
|
||||
function smarty_function_html_options_optoutput($key, $value, $selected) {
|
||||
if(!is_array($value)) {
|
||||
$_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
|
||||
smarty_function_escape_special_chars($key) . '"';
|
||||
if (in_array((string)$key, $selected))
|
||||
$_html_result .= ' selected="selected"';
|
||||
$_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
|
||||
} else {
|
||||
$_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($name)) {
|
||||
$_html_class = !empty($class) ? ' class="' . $class . '"' : '';
|
||||
$_html_id = !empty($id) ? ' id="' . $id . '"' : '';
|
||||
$_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
|
||||
}
|
||||
|
||||
return $_html_result;
|
||||
}
|
||||
|
||||
function smarty_function_html_options_optgroup($key, $values, $selected) {
|
||||
function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$_key = smarty_function_escape_special_chars($key);
|
||||
$_html_result = '<option value="' . $_key . '"';
|
||||
if (is_array($selected)) {
|
||||
if (isset($selected[$_key])) {
|
||||
$_html_result .= ' selected="selected"';
|
||||
}
|
||||
} elseif ($_key === $selected) {
|
||||
$_html_result .= ' selected="selected"';
|
||||
}
|
||||
$_html_class = !empty($class) ? ' class="' . $class . ' option"' : '';
|
||||
$_html_id = !empty($id) ? ' id="' . $id . '-' . $idx . '"' : '';
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = smarty_function_escape_special_chars((string) $value->__toString());
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = smarty_function_escape_special_chars((string) $value);
|
||||
}
|
||||
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
|
||||
$idx ++;
|
||||
} else {
|
||||
$_idx = 0;
|
||||
$_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null, $class, $_idx);
|
||||
$idx ++;
|
||||
}
|
||||
|
||||
return $_html_result;
|
||||
}
|
||||
|
||||
function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx)
|
||||
{
|
||||
$optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
|
||||
foreach ($values as $key => $value) {
|
||||
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
|
||||
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
|
||||
}
|
||||
$optgroup_html .= "</optgroup>\n";
|
||||
|
||||
return $optgroup_html;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,156 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {html_radios} function plugin
|
||||
*
|
||||
* File: function.html_radios.php<br>
|
||||
* Type: function<br>
|
||||
* Name: html_radios<br>
|
||||
* Date: 24.Feb.2003<br>
|
||||
* Purpose: Prints out a list of radio input types<br>
|
||||
* Input:<br>
|
||||
* - name (optional) - string default "radio"
|
||||
* - values (required) - array
|
||||
* - options (optional) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each radio button
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* Params:
|
||||
* <pre>
|
||||
* - name (optional) - string default "radio"
|
||||
* - values (required) - array
|
||||
* - options (required) - associative array
|
||||
* - checked (optional) - array default not set
|
||||
* - separator (optional) - ie <br> or
|
||||
* - output (optional) - the output next to each radio button
|
||||
* - assign (optional) - assign the output as an array to this variable
|
||||
* - escape (optional) - escape the content (not value), defaults to true
|
||||
* </pre>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {html_radios values=$ids output=$names}
|
||||
* {html_radios values=$ids name='box' separator='<br>' output=$names}
|
||||
* {html_radios values=$ids checked=$checked separator='<br>' output=$names}
|
||||
* </pre>
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
|
||||
* (Smarty online manual)
|
||||
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
* @param array
|
||||
* @param Smarty
|
||||
*
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
|
||||
* (Smarty online manual)
|
||||
* @author Christopher Kvarme <christopher.kvarme@flashjab.com>
|
||||
* @author credits to Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
* @uses smarty_function_escape_special_chars()
|
||||
*/
|
||||
function smarty_function_html_radios($params, &$smarty)
|
||||
function smarty_function_html_radios($params, $template)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
|
||||
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
|
||||
$name = 'radio';
|
||||
$values = null;
|
||||
$options = null;
|
||||
$selected = null;
|
||||
$separator = '';
|
||||
$escape = true;
|
||||
$labels = true;
|
||||
$label_ids = false;
|
||||
$output = null;
|
||||
$extra = '';
|
||||
|
||||
foreach($params as $_key => $_val) {
|
||||
switch($_key) {
|
||||
foreach ($params as $_key => $_val) {
|
||||
switch ($_key) {
|
||||
case 'name':
|
||||
case 'separator':
|
||||
$$_key = (string)$_val;
|
||||
$$_key = (string) $_val;
|
||||
break;
|
||||
|
||||
case 'checked':
|
||||
case 'selected':
|
||||
if(is_array($_val)) {
|
||||
$smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
|
||||
if (is_array($_val)) {
|
||||
trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
|
||||
} elseif (is_object($_val)) {
|
||||
if (method_exists($_val, "__toString")) {
|
||||
$selected = smarty_function_escape_special_chars((string) $_val->__toString());
|
||||
} else {
|
||||
trigger_error("html_radios: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE);
|
||||
}
|
||||
} else {
|
||||
$selected = (string)$_val;
|
||||
$selected = (string) $_val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'escape':
|
||||
case 'labels':
|
||||
case 'label_ids':
|
||||
$$_key = (bool)$_val;
|
||||
$$_key = (bool) $_val;
|
||||
break;
|
||||
|
||||
case 'options':
|
||||
$$_key = (array)$_val;
|
||||
$$_key = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'values':
|
||||
case 'output':
|
||||
$$_key = array_values((array)$_val);
|
||||
$$_key = array_values((array) $_val);
|
||||
break;
|
||||
|
||||
case 'radios':
|
||||
$smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array)$_val;
|
||||
trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
|
||||
$options = (array) $_val;
|
||||
break;
|
||||
|
||||
case 'assign':
|
||||
break;
|
||||
|
||||
case 'strict':
|
||||
break;
|
||||
|
||||
case 'disabled':
|
||||
case 'readonly':
|
||||
if (!empty($params['strict'])) {
|
||||
if (!is_scalar($_val)) {
|
||||
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
|
||||
}
|
||||
|
||||
if ($_val === true || $_val === $_key) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// omit break; to fall through!
|
||||
|
||||
default:
|
||||
if(!is_array($_val)) {
|
||||
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
|
||||
if (!is_array($_val)) {
|
||||
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
|
||||
} else {
|
||||
$smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($options) && !isset($values))
|
||||
return ''; /* raise error here? */
|
||||
if (!isset($options) && !isset($values)) {
|
||||
/* raise error here? */
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$_html_result = array();
|
||||
|
||||
if (isset($options)) {
|
||||
|
||||
foreach ($options as $_key=>$_val)
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
|
||||
|
||||
} else {
|
||||
|
||||
foreach ($values as $_i=>$_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
|
||||
foreach ($options as $_key => $_val) {
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!empty($params['assign'])) {
|
||||
$smarty->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n",$_html_result);
|
||||
foreach ($values as $_i => $_key) {
|
||||
$_val = isset($output[$_i]) ? $output[$_i] : '';
|
||||
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($params['assign'])) {
|
||||
$template->assign($params['assign'], $_html_result);
|
||||
} else {
|
||||
return implode("\n", $_html_result);
|
||||
}
|
||||
}
|
||||
|
||||
function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
|
||||
function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape)
|
||||
{
|
||||
$_output = '';
|
||||
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, "__toString")) {
|
||||
$value = (string) $value->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
if (is_object($output)) {
|
||||
if (method_exists($output, "__toString")) {
|
||||
$output = (string) $output->__toString();
|
||||
} else {
|
||||
trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE);
|
||||
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$output = (string) $output;
|
||||
}
|
||||
|
||||
if ($labels) {
|
||||
if($label_ids) {
|
||||
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
|
||||
$_output .= '<label for="' . $_id . '">';
|
||||
} else {
|
||||
$_output .= '<label>';
|
||||
}
|
||||
}
|
||||
$_output .= '<input type="radio" name="'
|
||||
. smarty_function_escape_special_chars($name) . '" value="'
|
||||
. smarty_function_escape_special_chars($value) . '"';
|
||||
if ($label_ids) {
|
||||
$_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
|
||||
$_output .= '<label for="' . $_id . '">';
|
||||
} else {
|
||||
$_output .= '<label>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
|
||||
$name = smarty_function_escape_special_chars($name);
|
||||
$value = smarty_function_escape_special_chars($value);
|
||||
if ($escape) {
|
||||
$output = smarty_function_escape_special_chars($output);
|
||||
}
|
||||
|
||||
if ((string)$value==$selected) {
|
||||
$_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
|
||||
|
||||
if ($labels && $label_ids) {
|
||||
$_output .= ' id="' . $_id . '"';
|
||||
}
|
||||
|
||||
if ($value === $selected) {
|
||||
$_output .= ' checked="checked"';
|
||||
}
|
||||
|
||||
$_output .= $extra . ' />' . $output;
|
||||
if ($labels) $_output .= '</label>';
|
||||
$_output .= $separator;
|
||||
if ($labels) {
|
||||
$_output .= '</label>';
|
||||
}
|
||||
|
||||
$_output .= $separator;
|
||||
|
||||
return $_output;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,99 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
|
||||
|
||||
/**
|
||||
* Smarty {html_select_date} plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: html_select_date<br>
|
||||
* Purpose: Prints the dropdowns for date selection.
|
||||
* ChangeLog:
|
||||
* <pre>
|
||||
* - 1.0 initial release
|
||||
* - 1.1 added support for +/- N syntax for begin
|
||||
* and end year values. (Monte)
|
||||
* - 1.2 added support for yyyy-mm-dd syntax for
|
||||
* time value. (Jan Rosier)
|
||||
* - 1.3 added support for choosing format for
|
||||
* month values (Gary Loescher)
|
||||
* - 1.3.1 added support for choosing format for
|
||||
* day values (Marcus Bointon)
|
||||
* - 1.3.2 support negative timestamps, force year
|
||||
* dropdown to include given date unless explicitly set (Monte)
|
||||
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
|
||||
* of 0000-00-00 dates (cybot, boots)
|
||||
* - 2.0 complete rewrite for performance,
|
||||
* added attributes month_names, *_id
|
||||
* </pre>
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
|
||||
* (Smarty online manual)
|
||||
* @version 2.0
|
||||
* @author Andrei Zmievski
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Rodney Rehm
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* ChangeLog:<br>
|
||||
* - 1.0 initial release
|
||||
* - 1.1 added support for +/- N syntax for begin
|
||||
* and end year values. (Monte)
|
||||
* - 1.2 added support for yyyy-mm-dd syntax for
|
||||
* time value. (Jan Rosier)
|
||||
* - 1.3 added support for choosing format for
|
||||
* month values (Gary Loescher)
|
||||
* - 1.3.1 added support for choosing format for
|
||||
* day values (Marcus Bointon)
|
||||
* - 1.3.2 support negative timestamps, force year
|
||||
* dropdown to include given date unless explicitly set (Monte)
|
||||
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
|
||||
* of 0000-00-00 dates (cybot, boots)
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
|
||||
* (Smarty online manual)
|
||||
* @version 1.3.4
|
||||
* @author Andrei Zmievski
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_html_select_date($params, &$smarty)
|
||||
function smarty_function_html_select_date($params)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
|
||||
require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
|
||||
require_once $smarty->_get_plugin_filepath('function','html_options');
|
||||
// generate timestamps used for month names only
|
||||
static $_month_timestamps = null;
|
||||
static $_current_year = null;
|
||||
if ($_month_timestamps === null) {
|
||||
$_current_year = date('Y');
|
||||
$_month_timestamps = array();
|
||||
for ($i = 1; $i <= 12; $i ++) {
|
||||
$_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default values. */
|
||||
$prefix = "Date_";
|
||||
$start_year = strftime("%Y");
|
||||
$end_year = $start_year;
|
||||
$display_days = true;
|
||||
$display_months = true;
|
||||
$display_years = true;
|
||||
$month_format = "%B";
|
||||
$prefix = "Date_";
|
||||
$start_year = null;
|
||||
$end_year = null;
|
||||
$display_days = true;
|
||||
$display_months = true;
|
||||
$display_years = true;
|
||||
$month_format = "%B";
|
||||
/* Write months as numbers by default GL */
|
||||
$month_value_format = "%m";
|
||||
$day_format = "%02d";
|
||||
$day_format = "%02d";
|
||||
/* Write day values using this format MB */
|
||||
$day_value_format = "%d";
|
||||
$year_as_text = false;
|
||||
$year_as_text = false;
|
||||
/* Display years in reverse order? Ie. 2000,1999,.... */
|
||||
$reverse_years = false;
|
||||
$reverse_years = false;
|
||||
/* Should the select boxes be part of an array when returned from PHP?
|
||||
e.g. setting it to "birthday", would create "birthday[Day]",
|
||||
"birthday[Month]" & "birthday[Year]". Can be combined with prefix */
|
||||
$field_array = null;
|
||||
$field_array = null;
|
||||
/* <select size>'s of the different <select> tags.
|
||||
If not set, uses default dropdown. */
|
||||
$day_size = null;
|
||||
$month_size = null;
|
||||
$year_size = null;
|
||||
$day_size = null;
|
||||
$month_size = null;
|
||||
$year_size = null;
|
||||
/* Unparsed attributes common to *ALL* the <select>/<input> tags.
|
||||
An example might be in the template: all_extra ='class ="foo"'. */
|
||||
$all_extra = null;
|
||||
$all_extra = null;
|
||||
/* Separate attributes for the tags. */
|
||||
$day_extra = null;
|
||||
$month_extra = null;
|
||||
$year_extra = null;
|
||||
$day_extra = null;
|
||||
$month_extra = null;
|
||||
$year_extra = null;
|
||||
/* Order in which to display the fields.
|
||||
"D" -> day, "M" -> month, "Y" -> year. */
|
||||
$field_order = 'MDY';
|
||||
$field_order = 'MDY';
|
||||
/* String printed between the different fields. */
|
||||
$field_separator = "\n";
|
||||
$time = time();
|
||||
$all_empty = null;
|
||||
$day_empty = null;
|
||||
$month_empty = null;
|
||||
$year_empty = null;
|
||||
$extra_attrs = '';
|
||||
$option_separator = "\n";
|
||||
$time = null;
|
||||
// $all_empty = null;
|
||||
// $day_empty = null;
|
||||
// $month_empty = null;
|
||||
// $year_empty = null;
|
||||
$extra_attrs = '';
|
||||
$all_id = null;
|
||||
$day_id = null;
|
||||
$month_id = null;
|
||||
$year_id = null;
|
||||
|
||||
foreach ($params as $_key=>$_value) {
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'prefix':
|
||||
case 'time':
|
||||
if (!is_array($_value) && $_value !== null) {
|
||||
$time = smarty_make_timestamp($_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'month_names':
|
||||
if (is_array($_value) && count($_value) == 12) {
|
||||
$$_key = $_value;
|
||||
} else {
|
||||
trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'prefix':
|
||||
case 'field_array':
|
||||
case 'start_year':
|
||||
case 'end_year':
|
||||
case 'month_format':
|
||||
case 'day_format':
|
||||
case 'day_value_format':
|
||||
case 'field_array':
|
||||
case 'month_format':
|
||||
case 'month_value_format':
|
||||
case 'day_size':
|
||||
case 'month_size':
|
||||
case 'year_size':
|
||||
@@ -103,16 +145,16 @@ function smarty_function_html_select_date($params, &$smarty)
|
||||
case 'year_extra':
|
||||
case 'field_order':
|
||||
case 'field_separator':
|
||||
case 'month_value_format':
|
||||
case 'option_separator':
|
||||
case 'all_empty':
|
||||
case 'month_empty':
|
||||
case 'day_empty':
|
||||
case 'year_empty':
|
||||
$$_key = (string)$_value;
|
||||
break;
|
||||
|
||||
case 'all_empty':
|
||||
$$_key = (string)$_value;
|
||||
$day_empty = $month_empty = $year_empty = $all_empty;
|
||||
case 'all_id':
|
||||
case 'month_id':
|
||||
case 'day_id':
|
||||
case 'year_id':
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'display_days':
|
||||
@@ -120,212 +162,226 @@ function smarty_function_html_select_date($params, &$smarty)
|
||||
case 'display_years':
|
||||
case 'year_as_text':
|
||||
case 'reverse_years':
|
||||
$$_key = (bool)$_value;
|
||||
$$_key = (bool) $_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!is_array($_value)) {
|
||||
$extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
|
||||
if (!is_array($_value)) {
|
||||
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
|
||||
} else {
|
||||
$smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('!^-\d+$!', $time)) {
|
||||
// negative timestamp, use date()
|
||||
$time = date('Y-m-d', $time);
|
||||
}
|
||||
// If $time is not in format yyyy-mm-dd
|
||||
if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
|
||||
$time = $found[1];
|
||||
// Note: date() is faster than strftime()
|
||||
// Note: explode(date()) is faster than date() date() date()
|
||||
if (isset($params['time']) && is_array($params['time'])) {
|
||||
if (isset($params['time'][$prefix . 'Year'])) {
|
||||
// $_REQUEST[$field_array] given
|
||||
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$prefix . $_elementName])
|
||||
? $params['time'][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
} elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
|
||||
// $_REQUEST given
|
||||
foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
|
||||
? $params['time'][$field_array][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
} else {
|
||||
// no date found, use NOW
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} elseif ($time === null) {
|
||||
if (array_key_exists('time', $params)) {
|
||||
$_year = $_month = $_day = $time = null;
|
||||
} else {
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} else {
|
||||
// use smarty_make_timestamp to get an unix timestamp and
|
||||
// strftime to make yyyy-mm-dd
|
||||
$time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
|
||||
}
|
||||
// Now split this in pieces, which later can be used to set the select
|
||||
$time = explode("-", $time);
|
||||
|
||||
// make syntax "+N" or "-N" work with start_year and end_year
|
||||
if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
|
||||
if ($match[1] == '+') {
|
||||
$end_year = strftime('%Y') + $match[2];
|
||||
// make syntax "+N" or "-N" work with $start_year and $end_year
|
||||
// Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
|
||||
foreach (array('start', 'end') as $key) {
|
||||
$key .= '_year';
|
||||
$t = $$key;
|
||||
if ($t === null) {
|
||||
$$key = (int) $_current_year;
|
||||
} elseif ($t[0] == '+') {
|
||||
$$key = (int) ($_current_year + (int)trim(substr($t, 1)));
|
||||
} elseif ($t[0] == '-') {
|
||||
$$key = (int) ($_current_year - (int)trim(substr($t, 1)));
|
||||
} else {
|
||||
$end_year = strftime('%Y') - $match[2];
|
||||
}
|
||||
}
|
||||
if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
|
||||
if ($match[1] == '+') {
|
||||
$start_year = strftime('%Y') + $match[2];
|
||||
} else {
|
||||
$start_year = strftime('%Y') - $match[2];
|
||||
}
|
||||
}
|
||||
if (strlen($time[0]) > 0) {
|
||||
if ($start_year > $time[0] && !isset($params['start_year'])) {
|
||||
// force start year to include given date if not explicitly set
|
||||
$start_year = $time[0];
|
||||
}
|
||||
if($end_year < $time[0] && !isset($params['end_year'])) {
|
||||
// force end year to include given date if not explicitly set
|
||||
$end_year = $time[0];
|
||||
$$key = (int) $$key;
|
||||
}
|
||||
}
|
||||
|
||||
$field_order = strtoupper($field_order);
|
||||
|
||||
$html_result = $month_result = $day_result = $year_result = "";
|
||||
|
||||
$field_separator_count = -1;
|
||||
if ($display_months) {
|
||||
$field_separator_count++;
|
||||
$month_names = array();
|
||||
$month_values = array();
|
||||
if(isset($month_empty)) {
|
||||
$month_names[''] = $month_empty;
|
||||
$month_values[''] = '';
|
||||
}
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
$month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
|
||||
$month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
|
||||
}
|
||||
|
||||
$month_result .= '<select name=';
|
||||
if (null !== $field_array){
|
||||
$month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
|
||||
} else {
|
||||
$month_result .= '"' . $prefix . 'Month"';
|
||||
}
|
||||
if (null !== $month_size){
|
||||
$month_result .= ' size="' . $month_size . '"';
|
||||
}
|
||||
if (null !== $month_extra){
|
||||
$month_result .= ' ' . $month_extra;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$month_result .= ' ' . $all_extra;
|
||||
}
|
||||
$month_result .= $extra_attrs . '>'."\n";
|
||||
|
||||
$month_result .= smarty_function_html_options(array('output' => $month_names,
|
||||
'values' => $month_values,
|
||||
'selected' => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$month_result .= '</select>';
|
||||
}
|
||||
|
||||
if ($display_days) {
|
||||
$field_separator_count++;
|
||||
$days = array();
|
||||
if (isset($day_empty)) {
|
||||
$days[''] = $day_empty;
|
||||
$day_values[''] = '';
|
||||
}
|
||||
for ($i = 1; $i <= 31; $i++) {
|
||||
$days[] = sprintf($day_format, $i);
|
||||
$day_values[] = sprintf($day_value_format, $i);
|
||||
}
|
||||
|
||||
$day_result .= '<select name=';
|
||||
if (null !== $field_array){
|
||||
$day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
|
||||
} else {
|
||||
$day_result .= '"' . $prefix . 'Day"';
|
||||
}
|
||||
if (null !== $day_size){
|
||||
$day_result .= ' size="' . $day_size . '"';
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$day_result .= ' ' . $all_extra;
|
||||
}
|
||||
if (null !== $day_extra){
|
||||
$day_result .= ' ' . $day_extra;
|
||||
}
|
||||
$day_result .= $extra_attrs . '>'."\n";
|
||||
$day_result .= smarty_function_html_options(array('output' => $days,
|
||||
'values' => $day_values,
|
||||
'selected' => $time[2],
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$day_result .= '</select>';
|
||||
// flip for ascending or descending
|
||||
if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
|
||||
$t = $end_year;
|
||||
$end_year = $start_year;
|
||||
$start_year = $t;
|
||||
}
|
||||
|
||||
// generate year <select> or <input>
|
||||
if ($display_years) {
|
||||
$field_separator_count++;
|
||||
if (null !== $field_array){
|
||||
$year_name = $field_array . '[' . $prefix . 'Year]';
|
||||
} else {
|
||||
$year_name = $prefix . 'Year';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($year_extra) {
|
||||
$_extra .= ' ' . $year_extra;
|
||||
}
|
||||
|
||||
if ($year_as_text) {
|
||||
$year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
|
||||
if (null !== $all_extra){
|
||||
$year_result .= ' ' . $all_extra;
|
||||
}
|
||||
if (null !== $year_extra){
|
||||
$year_result .= ' ' . $year_extra;
|
||||
}
|
||||
$year_result .= ' />';
|
||||
$_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
|
||||
} else {
|
||||
$years = range((int)$start_year, (int)$end_year);
|
||||
if ($reverse_years) {
|
||||
rsort($years, SORT_NUMERIC);
|
||||
} else {
|
||||
sort($years, SORT_NUMERIC);
|
||||
$_html_years = '<select name="' . $_name . '"';
|
||||
if ($year_id !== null || $all_id !== null) {
|
||||
$_html_years .= ' id="' . smarty_function_escape_special_chars(
|
||||
$year_id !== null ? ($year_id ? $year_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
$yearvals = $years;
|
||||
if(isset($year_empty)) {
|
||||
array_unshift($years, $year_empty);
|
||||
array_unshift($yearvals, '');
|
||||
if ($year_size) {
|
||||
$_html_years .= ' size="' . $year_size . '"';
|
||||
}
|
||||
$year_result .= '<select name="' . $year_name . '"';
|
||||
if (null !== $year_size){
|
||||
$year_result .= ' size="' . $year_size . '"';
|
||||
$_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($year_empty) || isset($all_empty)) {
|
||||
$_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$year_result .= ' ' . $all_extra;
|
||||
|
||||
$op = $start_year > $end_year ? - 1 : 1;
|
||||
for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
|
||||
$_html_years .= '<option value="' . $i . '"'
|
||||
. ($_year == $i ? ' selected="selected"' : '')
|
||||
. '>' . $i . '</option>' . $option_separator;
|
||||
}
|
||||
if (null !== $year_extra){
|
||||
$year_result .= ' ' . $year_extra;
|
||||
}
|
||||
$year_result .= $extra_attrs . '>'."\n";
|
||||
$year_result .= smarty_function_html_options(array('output' => $years,
|
||||
'values' => $yearvals,
|
||||
'selected' => $time[0],
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$year_result .= '</select>';
|
||||
|
||||
$_html_years .= '</select>';
|
||||
}
|
||||
}
|
||||
|
||||
// Loop thru the field_order field
|
||||
for ($i = 0; $i <= 2; $i++){
|
||||
$c = substr($field_order, $i, 1);
|
||||
switch ($c){
|
||||
case 'D':
|
||||
$html_result .= $day_result;
|
||||
break;
|
||||
// generate month <select> or <input>
|
||||
if ($display_months) {
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($month_extra) {
|
||||
$_extra .= ' ' . $month_extra;
|
||||
}
|
||||
|
||||
case 'M':
|
||||
$html_result .= $month_result;
|
||||
break;
|
||||
$_html_months = '<select name="' . $_name . '"';
|
||||
if ($month_id !== null || $all_id !== null) {
|
||||
$_html_months .= ' id="' . smarty_function_escape_special_chars(
|
||||
$month_id !== null ? ($month_id ? $month_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($month_size) {
|
||||
$_html_months .= ' size="' . $month_size . '"';
|
||||
}
|
||||
$_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($month_empty) || isset($all_empty)) {
|
||||
$_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= 12; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
|
||||
$_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
|
||||
$_html_months .= '<option value="' . $_value . '"'
|
||||
. ($_val == $_month ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_months .= '</select>';
|
||||
}
|
||||
|
||||
// generate day <select> or <input>
|
||||
if ($display_days) {
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if ($day_extra) {
|
||||
$_extra .= ' ' . $day_extra;
|
||||
}
|
||||
|
||||
$_html_days = '<select name="' . $_name . '"';
|
||||
if ($day_id !== null || $all_id !== null) {
|
||||
$_html_days .= ' id="' . smarty_function_escape_special_chars(
|
||||
$day_id !== null ? ($day_id ? $day_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
if ($day_size) {
|
||||
$_html_days .= ' size="' . $day_size . '"';
|
||||
}
|
||||
$_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($day_empty) || isset($all_empty)) {
|
||||
$_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= 31; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
|
||||
$_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i);
|
||||
$_html_days .= '<option value="' . $_value . '"'
|
||||
. ($_val == $_day ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_days .= '</select>';
|
||||
}
|
||||
|
||||
// order the fields for output
|
||||
$_html = '';
|
||||
for ($i = 0; $i <= 2; $i ++) {
|
||||
switch ($field_order[$i]) {
|
||||
case 'Y':
|
||||
$html_result .= $year_result;
|
||||
case 'y':
|
||||
if (isset($_html_years)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_years;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (isset($_html_months)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_months;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
if (isset($_html_days)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $_html_days;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Add the field seperator
|
||||
if($i < $field_separator_count) {
|
||||
$html_result .= $field_separator;
|
||||
}
|
||||
}
|
||||
|
||||
return $html_result;
|
||||
return $_html;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,62 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
|
||||
|
||||
/**
|
||||
* Smarty {html_select_time} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: html_select_time<br>
|
||||
* Purpose: Prints the dropdowns for time selection
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
|
||||
* (Smarty online manual)
|
||||
* @author Roberto Berto <roberto@berto.net>
|
||||
* @credits Monte Ohrt <monte AT ohrt DOT com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
|
||||
* (Smarty online manual)
|
||||
* @author Roberto Berto <roberto@berto.net>
|
||||
* @author Monte Ohrt <monte AT ohrt DOT com>
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
* @uses smarty_make_timestamp()
|
||||
* @uses smarty_make_timestamp()
|
||||
*/
|
||||
function smarty_function_html_select_time($params, &$smarty)
|
||||
function smarty_function_html_select_time($params)
|
||||
{
|
||||
require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
|
||||
require_once $smarty->_get_plugin_filepath('function','html_options');
|
||||
/* Default values. */
|
||||
$prefix = "Time_";
|
||||
$time = time();
|
||||
$display_hours = true;
|
||||
$display_minutes = true;
|
||||
$display_seconds = true;
|
||||
$display_meridian = true;
|
||||
$use_24_hours = true;
|
||||
$minute_interval = 1;
|
||||
$second_interval = 1;
|
||||
/* Should the select boxes be part of an array when returned from PHP?
|
||||
e.g. setting it to "birthday", would create "birthday[Hour]",
|
||||
"birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
|
||||
Can be combined with prefix. */
|
||||
$field_array = null;
|
||||
$all_extra = null;
|
||||
$hour_extra = null;
|
||||
$minute_extra = null;
|
||||
$second_extra = null;
|
||||
$meridian_extra = null;
|
||||
$prefix = "Time_";
|
||||
$field_array = null;
|
||||
$field_separator = "\n";
|
||||
$option_separator = "\n";
|
||||
$time = null;
|
||||
|
||||
foreach ($params as $_key=>$_value) {
|
||||
$display_hours = true;
|
||||
$display_minutes = true;
|
||||
$display_seconds = true;
|
||||
$display_meridian = true;
|
||||
|
||||
$hour_format = '%02d';
|
||||
$hour_value_format = '%02d';
|
||||
$minute_format = '%02d';
|
||||
$minute_value_format = '%02d';
|
||||
$second_format = '%02d';
|
||||
$second_value_format = '%02d';
|
||||
|
||||
$hour_size = null;
|
||||
$minute_size = null;
|
||||
$second_size = null;
|
||||
$meridian_size = null;
|
||||
|
||||
$all_empty = null;
|
||||
$hour_empty = null;
|
||||
$minute_empty = null;
|
||||
$second_empty = null;
|
||||
$meridian_empty = null;
|
||||
|
||||
$all_id = null;
|
||||
$hour_id = null;
|
||||
$minute_id = null;
|
||||
$second_id = null;
|
||||
$meridian_id = null;
|
||||
|
||||
$use_24_hours = true;
|
||||
$minute_interval = 1;
|
||||
$second_interval = 1;
|
||||
|
||||
$extra_attrs = '';
|
||||
$all_extra = null;
|
||||
$hour_extra = null;
|
||||
$minute_extra = null;
|
||||
$second_extra = null;
|
||||
$meridian_extra = null;
|
||||
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'prefix':
|
||||
case 'time':
|
||||
if (!is_array($_value) && $_value !== null) {
|
||||
$time = smarty_make_timestamp($_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'prefix':
|
||||
case 'field_array':
|
||||
|
||||
case 'field_separator':
|
||||
case 'option_separator':
|
||||
|
||||
case 'all_extra':
|
||||
case 'hour_extra':
|
||||
case 'minute_extra':
|
||||
case 'second_extra':
|
||||
case 'meridian_extra':
|
||||
$$_key = (string)$_value;
|
||||
|
||||
case 'all_empty':
|
||||
case 'hour_empty':
|
||||
case 'minute_empty':
|
||||
case 'second_empty':
|
||||
case 'meridian_empty':
|
||||
|
||||
case 'all_id':
|
||||
case 'hour_id':
|
||||
case 'minute_id':
|
||||
case 'second_id':
|
||||
case 'meridian_id':
|
||||
|
||||
case 'hour_format':
|
||||
case 'hour_value_format':
|
||||
case 'minute_format':
|
||||
case 'minute_value_format':
|
||||
case 'second_format':
|
||||
case 'second_value_format':
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'display_hours':
|
||||
@@ -64,131 +125,240 @@ function smarty_function_html_select_time($params, &$smarty)
|
||||
case 'display_seconds':
|
||||
case 'display_meridian':
|
||||
case 'use_24_hours':
|
||||
$$_key = (bool)$_value;
|
||||
$$_key = (bool) $_value;
|
||||
break;
|
||||
|
||||
case 'minute_interval':
|
||||
case 'second_interval':
|
||||
$$_key = (int)$_value;
|
||||
|
||||
case 'hour_size':
|
||||
case 'minute_size':
|
||||
case 'second_size':
|
||||
case 'meridian_size':
|
||||
$$_key = (int) $_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
$smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
|
||||
if (!is_array($_value)) {
|
||||
$extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
|
||||
} else {
|
||||
trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$time = smarty_make_timestamp($time);
|
||||
|
||||
$html_result = '';
|
||||
if (isset($params['time']) && is_array($params['time'])) {
|
||||
if (isset($params['time'][$prefix . 'Hour'])) {
|
||||
// $_REQUEST[$field_array] given
|
||||
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$prefix . $_elementName])
|
||||
? $params['time'][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
$_meridian = isset($params['time'][$prefix . 'Meridian'])
|
||||
? (' ' . $params['time'][$prefix . 'Meridian'])
|
||||
: '';
|
||||
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
} elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) {
|
||||
// $_REQUEST given
|
||||
foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
|
||||
$_variableName = '_' . strtolower($_elementName);
|
||||
$$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
|
||||
? $params['time'][$field_array][$prefix . $_elementName]
|
||||
: date($_elementKey);
|
||||
}
|
||||
$_meridian = isset($params['time'][$field_array][$prefix . 'Meridian'])
|
||||
? (' ' . $params['time'][$field_array][$prefix . 'Meridian'])
|
||||
: '';
|
||||
$time = strtotime($_hour . ':' . $_minute . ':' . $_second . $_meridian);
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
} else {
|
||||
// no date found, use NOW
|
||||
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
|
||||
}
|
||||
} elseif ($time === null) {
|
||||
if (array_key_exists('time', $params)) {
|
||||
$_hour = $_minute = $_second = $time = null;
|
||||
} else {
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
|
||||
}
|
||||
} else {
|
||||
list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
|
||||
}
|
||||
|
||||
// generate hour <select>
|
||||
if ($display_hours) {
|
||||
$hours = $use_24_hours ? range(0, 23) : range(1, 12);
|
||||
$hour_fmt = $use_24_hours ? '%H' : '%I';
|
||||
for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
|
||||
$hours[$i] = sprintf('%02d', $hours[$i]);
|
||||
$html_result .= '<select name=';
|
||||
if (null !== $field_array) {
|
||||
$html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
|
||||
} else {
|
||||
$html_result .= '"' . $prefix . 'Hour"';
|
||||
$_html_hours = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if (null !== $hour_extra){
|
||||
$html_result .= ' ' . $hour_extra;
|
||||
if ($hour_extra) {
|
||||
$_extra .= ' ' . $hour_extra;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$html_result .= ' ' . $all_extra;
|
||||
|
||||
$_html_hours = '<select name="' . $_name . '"';
|
||||
if ($hour_id !== null || $all_id !== null) {
|
||||
$_html_hours .= ' id="' . smarty_function_escape_special_chars(
|
||||
$hour_id !== null ? ($hour_id ? $hour_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
$html_result .= '>'."\n";
|
||||
$html_result .= smarty_function_html_options(array('output' => $hours,
|
||||
'values' => $hours,
|
||||
'selected' => strftime($hour_fmt, $time),
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$html_result .= "</select>\n";
|
||||
if ($hour_size) {
|
||||
$_html_hours .= ' size="' . $hour_size . '"';
|
||||
}
|
||||
$_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($hour_empty) || isset($all_empty)) {
|
||||
$_html_hours .= '<option value="">' . (isset($hour_empty) ? $hour_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$start = $use_24_hours ? 0 : 1;
|
||||
$end = $use_24_hours ? 23 : 12;
|
||||
for ($i = $start; $i <= $end; $i ++) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
|
||||
$_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
|
||||
|
||||
if (!$use_24_hours) {
|
||||
$_hour12 = $_hour == 0
|
||||
? 12
|
||||
: ($_hour <= 12 ? $_hour : $_hour - 12);
|
||||
}
|
||||
|
||||
$selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
|
||||
$_html_hours .= '<option value="' . $_value . '"'
|
||||
. ($selected ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_hours .= '</select>';
|
||||
}
|
||||
|
||||
// generate minute <select>
|
||||
if ($display_minutes) {
|
||||
$all_minutes = range(0, 59);
|
||||
for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
|
||||
$minutes[] = sprintf('%02d', $all_minutes[$i]);
|
||||
$selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
|
||||
$html_result .= '<select name=';
|
||||
if (null !== $field_array) {
|
||||
$html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
|
||||
} else {
|
||||
$html_result .= '"' . $prefix . 'Minute"';
|
||||
$_html_minutes = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
if (null !== $minute_extra){
|
||||
$html_result .= ' ' . $minute_extra;
|
||||
if ($minute_extra) {
|
||||
$_extra .= ' ' . $minute_extra;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$html_result .= ' ' . $all_extra;
|
||||
|
||||
$_html_minutes = '<select name="' . $_name . '"';
|
||||
if ($minute_id !== null || $all_id !== null) {
|
||||
$_html_minutes .= ' id="' . smarty_function_escape_special_chars(
|
||||
$minute_id !== null ? ($minute_id ? $minute_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
$html_result .= '>'."\n";
|
||||
|
||||
$html_result .= smarty_function_html_options(array('output' => $minutes,
|
||||
'values' => $minutes,
|
||||
'selected' => $selected,
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$html_result .= "</select>\n";
|
||||
if ($minute_size) {
|
||||
$_html_minutes .= ' size="' . $minute_size . '"';
|
||||
}
|
||||
$_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($minute_empty) || isset($all_empty)) {
|
||||
$_html_minutes .= '<option value="">' . (isset($minute_empty) ? $minute_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
|
||||
for ($i = 0; $i <= 59; $i += $minute_interval) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
|
||||
$_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
|
||||
$_html_minutes .= '<option value="' . $_value . '"'
|
||||
. ($selected === $i ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_minutes .= '</select>';
|
||||
}
|
||||
|
||||
// generate second <select>
|
||||
if ($display_seconds) {
|
||||
$all_seconds = range(0, 59);
|
||||
for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
|
||||
$seconds[] = sprintf('%02d', $all_seconds[$i]);
|
||||
$selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
|
||||
$html_result .= '<select name=';
|
||||
if (null !== $field_array) {
|
||||
$html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
|
||||
} else {
|
||||
$html_result .= '"' . $prefix . 'Second"';
|
||||
$_html_seconds = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
|
||||
if (null !== $second_extra){
|
||||
$html_result .= ' ' . $second_extra;
|
||||
if ($second_extra) {
|
||||
$_extra .= ' ' . $second_extra;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$html_result .= ' ' . $all_extra;
|
||||
|
||||
$_html_seconds = '<select name="' . $_name . '"';
|
||||
if ($second_id !== null || $all_id !== null) {
|
||||
$_html_seconds .= ' id="' . smarty_function_escape_special_chars(
|
||||
$second_id !== null ? ($second_id ? $second_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
$html_result .= '>'."\n";
|
||||
|
||||
$html_result .= smarty_function_html_options(array('output' => $seconds,
|
||||
'values' => $seconds,
|
||||
'selected' => $selected,
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$html_result .= "</select>\n";
|
||||
if ($second_size) {
|
||||
$_html_seconds .= ' size="' . $second_size . '"';
|
||||
}
|
||||
$_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($second_empty) || isset($all_empty)) {
|
||||
$_html_seconds .= '<option value="">' . (isset($second_empty) ? $second_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
|
||||
for ($i = 0; $i <= 59; $i += $second_interval) {
|
||||
$_val = sprintf('%02d', $i);
|
||||
$_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
|
||||
$_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
|
||||
$_html_seconds .= '<option value="' . $_value . '"'
|
||||
. ($selected === $i ? ' selected="selected"' : '')
|
||||
. '>' . $_text . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_seconds .= '</select>';
|
||||
}
|
||||
|
||||
// generate meridian <select>
|
||||
if ($display_meridian && !$use_24_hours) {
|
||||
$html_result .= '<select name=';
|
||||
if (null !== $field_array) {
|
||||
$html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
|
||||
} else {
|
||||
$html_result .= '"' . $prefix . 'Meridian"';
|
||||
$_html_meridian = '';
|
||||
$_extra = '';
|
||||
$_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
|
||||
if ($all_extra) {
|
||||
$_extra .= ' ' . $all_extra;
|
||||
}
|
||||
|
||||
if (null !== $meridian_extra){
|
||||
$html_result .= ' ' . $meridian_extra;
|
||||
if ($meridian_extra) {
|
||||
$_extra .= ' ' . $meridian_extra;
|
||||
}
|
||||
if (null !== $all_extra){
|
||||
$html_result .= ' ' . $all_extra;
|
||||
|
||||
$_html_meridian = '<select name="' . $_name . '"';
|
||||
if ($meridian_id !== null || $all_id !== null) {
|
||||
$_html_meridian .= ' id="' . smarty_function_escape_special_chars(
|
||||
$meridian_id !== null ? ($meridian_id ? $meridian_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
|
||||
) . '"';
|
||||
}
|
||||
$html_result .= '>'."\n";
|
||||
|
||||
$html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
|
||||
'values' => array('am', 'pm'),
|
||||
'selected' => strtolower(strftime('%p', $time)),
|
||||
'print_result' => false),
|
||||
$smarty);
|
||||
$html_result .= "</select>\n";
|
||||
if ($meridian_size) {
|
||||
$_html_meridian .= ' size="' . $meridian_size . '"';
|
||||
}
|
||||
$_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
|
||||
|
||||
if (isset($meridian_empty) || isset($all_empty)) {
|
||||
$_html_meridian .= '<option value="">' . (isset($meridian_empty) ? $meridian_empty : $all_empty) . '</option>' . $option_separator;
|
||||
}
|
||||
|
||||
$_html_meridian .= '<option value="am"' . ($_hour > 0 && $_hour < 12 ? ' selected="selected"' : '') . '>AM</option>' . $option_separator
|
||||
. '<option value="pm"' . ($_hour < 12 ? '' : ' selected="selected"') . '>PM</option>' . $option_separator
|
||||
. '</select>';
|
||||
}
|
||||
|
||||
return $html_result;
|
||||
$_html = '';
|
||||
foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
|
||||
if (isset($$k)) {
|
||||
if ($_html) {
|
||||
$_html .= $field_separator;
|
||||
}
|
||||
$_html .= $$k;
|
||||
}
|
||||
}
|
||||
|
||||
return $_html;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,52 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {html_table} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: html_table<br>
|
||||
* Date: Feb 17, 2003<br>
|
||||
* Purpose: make an html table from an array of data<br>
|
||||
* Input:<br>
|
||||
* - loop = array to loop through
|
||||
* - cols = number of columns, comma separated list of column names
|
||||
* or array of column names
|
||||
* - rows = number of rows
|
||||
* - table_attr = table attributes
|
||||
* - th_attr = table heading attributes (arrays are cycled)
|
||||
* - tr_attr = table row attributes (arrays are cycled)
|
||||
* - td_attr = table cell attributes (arrays are cycled)
|
||||
* - trailpad = value to pad trailing cells with
|
||||
* - caption = text for caption element
|
||||
* - vdir = vertical direction (default: "down", means top-to-bottom)
|
||||
* - hdir = horizontal direction (default: "right", means left-to-right)
|
||||
* - inner = inner loop (default "cols": print $loop line by line,
|
||||
* $loop will be printed column by column otherwise)
|
||||
*
|
||||
*
|
||||
* Params:
|
||||
* <pre>
|
||||
* - loop - array to loop through
|
||||
* - cols - number of columns, comma separated list of column names
|
||||
* or array of column names
|
||||
* - rows - number of rows
|
||||
* - table_attr - table attributes
|
||||
* - th_attr - table heading attributes (arrays are cycled)
|
||||
* - tr_attr - table row attributes (arrays are cycled)
|
||||
* - td_attr - table cell attributes (arrays are cycled)
|
||||
* - trailpad - value to pad trailing cells with
|
||||
* - caption - text for caption element
|
||||
* - vdir - vertical direction (default: "down", means top-to-bottom)
|
||||
* - hdir - horizontal direction (default: "right", means left-to-right)
|
||||
* - inner - inner loop (default "cols": print $loop line by line,
|
||||
* $loop will be printed column by column otherwise)
|
||||
* </pre>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {table loop=$data}
|
||||
* {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
|
||||
* {table loop=$data cols="first,second,third" tr_attr=$colors}
|
||||
* </pre>
|
||||
*
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credit to Messju Mohr <messju at lammfellpuschen dot de>
|
||||
* @author credit to boots <boots dot smarty at yahoo dot com>
|
||||
* @author credit to Messju Mohr <messju at lammfellpuschen dot de>
|
||||
* @author credit to boots <boots dot smarty at yahoo dot com>
|
||||
* @version 1.1
|
||||
* @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
|
||||
* (Smarty online manual)
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_html_table($params, &$smarty)
|
||||
function smarty_function_html_table($params)
|
||||
{
|
||||
$table_attr = 'border="1"';
|
||||
$tr_attr = '';
|
||||
@@ -59,16 +60,18 @@ function smarty_function_html_table($params, &$smarty)
|
||||
$hdir = 'right';
|
||||
$inner = 'cols';
|
||||
$caption = '';
|
||||
$loop = null;
|
||||
|
||||
if (!isset($params['loop'])) {
|
||||
$smarty->trigger_error("html_table: missing 'loop' parameter");
|
||||
trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($params as $_key=>$_value) {
|
||||
foreach ($params as $_key => $_value) {
|
||||
switch ($_key) {
|
||||
case 'loop':
|
||||
$$_key = (array)$_value;
|
||||
$$_key = (array) $_value;
|
||||
break;
|
||||
|
||||
case 'cols':
|
||||
@@ -79,14 +82,14 @@ function smarty_function_html_table($params, &$smarty)
|
||||
$cols = explode(',', $_value);
|
||||
$cols_count = count($cols);
|
||||
} elseif (!empty($_value)) {
|
||||
$cols_count = (int)$_value;
|
||||
$cols_count = (int) $_value;
|
||||
} else {
|
||||
$cols_count = $cols;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rows':
|
||||
$$_key = (int)$_value;
|
||||
$$_key = (int) $_value;
|
||||
break;
|
||||
|
||||
case 'table_attr':
|
||||
@@ -95,7 +98,7 @@ function smarty_function_html_table($params, &$smarty)
|
||||
case 'vdir':
|
||||
case 'inner':
|
||||
case 'caption':
|
||||
$$_key = (string)$_value;
|
||||
$$_key = (string) $_value;
|
||||
break;
|
||||
|
||||
case 'tr_attr':
|
||||
@@ -109,11 +112,11 @@ function smarty_function_html_table($params, &$smarty)
|
||||
$loop_count = count($loop);
|
||||
if (empty($params['rows'])) {
|
||||
/* no rows specified */
|
||||
$rows = ceil($loop_count/$cols_count);
|
||||
$rows = ceil($loop_count / $cols_count);
|
||||
} elseif (empty($params['cols'])) {
|
||||
if (!empty($params['rows'])) {
|
||||
/* no cols specified, but rows */
|
||||
$cols_count = ceil($loop_count/$rows);
|
||||
$cols_count = ceil($loop_count / $rows);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +130,7 @@ function smarty_function_html_table($params, &$smarty)
|
||||
$cols = ($hdir == 'right') ? $cols : array_reverse($cols);
|
||||
$output .= "<thead><tr>\n";
|
||||
|
||||
for ($r=0; $r<$cols_count; $r++) {
|
||||
for ($r = 0; $r < $cols_count; $r ++) {
|
||||
$output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
|
||||
$output .= $cols[$r];
|
||||
$output .= "</th>\n";
|
||||
@@ -136,18 +139,18 @@ function smarty_function_html_table($params, &$smarty)
|
||||
}
|
||||
|
||||
$output .= "<tbody>\n";
|
||||
for ($r=0; $r<$rows; $r++) {
|
||||
for ($r = 0; $r < $rows; $r ++) {
|
||||
$output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
|
||||
$rx = ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
|
||||
$rx = ($vdir == 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count;
|
||||
|
||||
for ($c=0; $c<$cols_count; $c++) {
|
||||
$x = ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
|
||||
if ($inner!='cols') {
|
||||
for ($c = 0; $c < $cols_count; $c ++) {
|
||||
$x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count - 1 - $c;
|
||||
if ($inner != 'cols') {
|
||||
/* shuffle x to loop over rows*/
|
||||
$x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
|
||||
$x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
|
||||
}
|
||||
|
||||
if ($x<$loop_count) {
|
||||
if ($x < $loop_count) {
|
||||
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
|
||||
} else {
|
||||
$output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
|
||||
@@ -157,21 +160,17 @@ function smarty_function_html_table($params, &$smarty)
|
||||
}
|
||||
$output .= "</tbody>\n";
|
||||
$output .= "</table>\n";
|
||||
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function smarty_function_html_table_cycle($name, $var, $no) {
|
||||
if(!is_array($var)) {
|
||||
function smarty_function_html_table_cycle($name, $var, $no)
|
||||
{
|
||||
if (!is_array($var)) {
|
||||
$ret = $var;
|
||||
} else {
|
||||
$ret = $var[$no % count($var)];
|
||||
}
|
||||
|
||||
return ($ret) ? ' '.$ret : '';
|
||||
|
||||
return ($ret) ? ' ' . $ret : '';
|
||||
}
|
||||
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {mailto} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: mailto<br>
|
||||
* Date: May 21, 2002
|
||||
* Purpose: automate mailto address link creation, and optionally
|
||||
* encode them.<br>
|
||||
* Input:<br>
|
||||
* - address = e-mail address
|
||||
* - text = (optional) text to display, default is address
|
||||
* - encode = (optional) can be one of:
|
||||
* * none : no encoding (default)
|
||||
* * javascript : encode with javascript
|
||||
* * javascript_charcode : encode with javascript charcode
|
||||
* * hex : encode with hexidecimal (no javascript)
|
||||
* - cc = (optional) address(es) to carbon copy
|
||||
* - bcc = (optional) address(es) to blind carbon copy
|
||||
* - subject = (optional) e-mail subject
|
||||
* - newsgroups = (optional) newsgroup(s) to post to
|
||||
* - followupto = (optional) address(es) to follow up to
|
||||
* - extra = (optional) extra tags for the href link
|
||||
*
|
||||
* Purpose: automate mailto address link creation, and optionally encode them.<br>
|
||||
* Params:
|
||||
* <pre>
|
||||
* - address - (required) - e-mail address
|
||||
* - text - (optional) - text to display, default is address
|
||||
* - encode - (optional) - can be one of:
|
||||
* * none : no encoding (default)
|
||||
* * javascript : encode with javascript
|
||||
* * javascript_charcode : encode with javascript charcode
|
||||
* * hex : encode with hexidecimal (no javascript)
|
||||
* - cc - (optional) - address(es) to carbon copy
|
||||
* - bcc - (optional) - address(es) to blind carbon copy
|
||||
* - subject - (optional) - e-mail subject
|
||||
* - newsgroups - (optional) - newsgroup(s) to post to
|
||||
* - followupto - (optional) - address(es) to follow up to
|
||||
* - extra - (optional) - extra tags for the href link
|
||||
* </pre>
|
||||
* Examples:
|
||||
* <pre>
|
||||
* {mailto address="me@domain.com"}
|
||||
@@ -38,45 +37,49 @@
|
||||
* {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
|
||||
* {mailto address="me@domain.com" extra='class="mailto"'}
|
||||
* </pre>
|
||||
* @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
|
||||
* (Smarty online manual)
|
||||
* @version 1.2
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author credits to Jason Sweat (added cc, bcc and subject functionality)
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string
|
||||
*
|
||||
* @param array $params parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_mailto($params, &$smarty)
|
||||
function smarty_function_mailto($params)
|
||||
{
|
||||
static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
|
||||
$extra = '';
|
||||
|
||||
if (empty($params['address'])) {
|
||||
$smarty->trigger_error("mailto: missing 'address' parameter");
|
||||
trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
} else {
|
||||
$address = $params['address'];
|
||||
}
|
||||
|
||||
$text = $address;
|
||||
|
||||
// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
|
||||
// so, don't encode it.
|
||||
$search = array('%40', '%2C');
|
||||
$replace = array('@', ',');
|
||||
$replace = array('@', ',');
|
||||
$mail_parms = array();
|
||||
foreach ($params as $var=>$value) {
|
||||
foreach ($params as $var => $value) {
|
||||
switch ($var) {
|
||||
case 'cc':
|
||||
case 'bcc':
|
||||
case 'followupto':
|
||||
if (!empty($value))
|
||||
$mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
|
||||
if (!empty($value)) {
|
||||
$mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'subject':
|
||||
case 'newsgroups':
|
||||
$mail_parms[] = $var.'='.rawurlencode($value);
|
||||
$mail_parms[] = $var . '=' . rawurlencode($value);
|
||||
break;
|
||||
|
||||
case 'extra':
|
||||
@@ -87,79 +90,66 @@ function smarty_function_mailto($params, &$smarty)
|
||||
}
|
||||
}
|
||||
|
||||
$mail_parm_vals = '';
|
||||
for ($i=0; $i<count($mail_parms); $i++) {
|
||||
$mail_parm_vals .= (0==$i) ? '?' : '&';
|
||||
$mail_parm_vals .= $mail_parms[$i];
|
||||
if ($mail_parms) {
|
||||
$address .= '?' . join('&', $mail_parms);
|
||||
}
|
||||
$address .= $mail_parm_vals;
|
||||
|
||||
$encode = (empty($params['encode'])) ? 'none' : $params['encode'];
|
||||
if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
|
||||
$smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
|
||||
if (!isset($_allowed_encoding[$encode])) {
|
||||
trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($encode == 'javascript' ) {
|
||||
$string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
|
||||
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
|
||||
if ($encode == 'javascript') {
|
||||
$string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
|
||||
|
||||
$js_encode = '';
|
||||
for ($x=0; $x < strlen($string); $x++) {
|
||||
for ($x = 0, $_length = strlen($string); $x < $_length; $x ++) {
|
||||
$js_encode .= '%' . bin2hex($string[$x]);
|
||||
}
|
||||
|
||||
return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
|
||||
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
|
||||
} elseif ($encode == 'javascript_charcode') {
|
||||
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
|
||||
|
||||
} elseif ($encode == 'javascript_charcode' ) {
|
||||
$string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
|
||||
|
||||
for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
|
||||
$ord[] = ord($string[$x]);
|
||||
for ($x = 0, $y = strlen($string); $x < $y; $x ++) {
|
||||
$ord[] = ord($string[$x]);
|
||||
}
|
||||
|
||||
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
|
||||
$_ret .= "<!--\n";
|
||||
$_ret .= "{document.write(String.fromCharCode(";
|
||||
$_ret .= implode(',',$ord);
|
||||
$_ret .= "))";
|
||||
$_ret .= "}\n";
|
||||
$_ret .= "//-->\n";
|
||||
$_ret .= "</script>\n";
|
||||
|
||||
return $_ret;
|
||||
|
||||
|
||||
} elseif ($encode == 'hex') {
|
||||
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"
|
||||
. "{document.write(String.fromCharCode("
|
||||
. implode(',', $ord)
|
||||
. "))"
|
||||
. "}\n"
|
||||
. "</script>\n";
|
||||
|
||||
return $_ret;
|
||||
} elseif ($encode == 'hex') {
|
||||
preg_match('!^(.*)(\?.*)$!', $address, $match);
|
||||
if (!empty($match[2])) {
|
||||
trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.", E_USER_WARNING);
|
||||
|
||||
preg_match('!^(.*)(\?.*)$!',$address,$match);
|
||||
if(!empty($match[2])) {
|
||||
$smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
|
||||
return;
|
||||
}
|
||||
$address_encode = '';
|
||||
for ($x=0; $x < strlen($address); $x++) {
|
||||
if(preg_match('!\w!',$address[$x])) {
|
||||
for ($x = 0, $_length = strlen($address); $x < $_length; $x ++) {
|
||||
if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) {
|
||||
$address_encode .= '%' . bin2hex($address[$x]);
|
||||
} else {
|
||||
$address_encode .= $address[$x];
|
||||
}
|
||||
}
|
||||
$text_encode = '';
|
||||
for ($x=0; $x < strlen($text); $x++) {
|
||||
$text_encode .= '&#x' . bin2hex($text[$x]).';';
|
||||
for ($x = 0, $_length = strlen($text); $x < $_length; $x ++) {
|
||||
$text_encode .= '&#x' . bin2hex($text[$x]) . ';';
|
||||
}
|
||||
|
||||
$mailto = "mailto:";
|
||||
return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
|
||||
|
||||
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
|
||||
} else {
|
||||
// no encoding
|
||||
return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
|
||||
|
||||
return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,85 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
* This plugin is only for Smarty2 BC
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {math} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: math<br>
|
||||
* Purpose: handle math computations in template<br>
|
||||
* @link http://smarty.php.net/manual/en/language.function.math.php {math}
|
||||
* (Smarty online manual)
|
||||
* Purpose: handle math computations in template
|
||||
*
|
||||
* @link http://www.smarty.net/manual/en/language.function.math.php {math}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param Smarty_Internal_Template $template template object
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function smarty_function_math($params, &$smarty)
|
||||
function smarty_function_math($params, $template)
|
||||
{
|
||||
static $_allowed_funcs = array(
|
||||
'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
|
||||
'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
|
||||
'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true
|
||||
);
|
||||
// be sure equation parameter is present
|
||||
if (empty($params['equation'])) {
|
||||
$smarty->trigger_error("math: missing equation parameter");
|
||||
trigger_error("math: missing equation parameter", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// strip out backticks, not necessary for math
|
||||
$equation = str_replace('`','',$params['equation']);
|
||||
$equation = $params['equation'];
|
||||
|
||||
// make sure parenthesis are balanced
|
||||
if (substr_count($equation,"(") != substr_count($equation,")")) {
|
||||
$smarty->trigger_error("math: unbalanced parenthesis");
|
||||
if (substr_count($equation, "(") != substr_count($equation, ")")) {
|
||||
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// match all vars in equation, make sure all are passed
|
||||
preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
|
||||
$allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
|
||||
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
|
||||
|
||||
foreach($match[1] as $curr_var) {
|
||||
if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
|
||||
$smarty->trigger_error("math: function call $curr_var not allowed");
|
||||
preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!", $equation, $match);
|
||||
|
||||
foreach ($match[1] as $curr_var) {
|
||||
if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
|
||||
trigger_error("math: function call $curr_var not allowed", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($params as $key => $val) {
|
||||
foreach ($params as $key => $val) {
|
||||
if ($key != "equation" && $key != "format" && $key != "assign") {
|
||||
// make sure value is not empty
|
||||
if (strlen($val)==0) {
|
||||
$smarty->trigger_error("math: parameter $key is empty");
|
||||
if (strlen($val) == 0) {
|
||||
trigger_error("math: parameter $key is empty", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!is_numeric($val)) {
|
||||
$smarty->trigger_error("math: parameter $key: is not numeric");
|
||||
trigger_error("math: parameter $key: is not numeric", E_USER_WARNING);
|
||||
|
||||
return;
|
||||
}
|
||||
$equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
|
||||
}
|
||||
}
|
||||
|
||||
eval("\$smarty_math_result = ".$equation.";");
|
||||
$smarty_math_result = null;
|
||||
eval("\$smarty_math_result = " . $equation . ";");
|
||||
|
||||
if (empty($params['format'])) {
|
||||
if (empty($params['assign'])) {
|
||||
return $smarty_math_result;
|
||||
} else {
|
||||
$smarty->assign($params['assign'],$smarty_math_result);
|
||||
$template->assign($params['assign'], $smarty_math_result);
|
||||
}
|
||||
} else {
|
||||
if (empty($params['assign'])){
|
||||
printf($params['format'],$smarty_math_result);
|
||||
if (empty($params['assign'])) {
|
||||
printf($params['format'], $smarty_math_result);
|
||||
} else {
|
||||
$smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
|
||||
$template->assign($params['assign'], sprintf($params['format'], $smarty_math_result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {popup} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: popup<br>
|
||||
* Purpose: make text pop up in windows via overlib
|
||||
* @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_popup($params, &$smarty)
|
||||
{
|
||||
$append = '';
|
||||
foreach ($params as $_key=>$_value) {
|
||||
switch ($_key) {
|
||||
case 'text':
|
||||
case 'trigger':
|
||||
case 'function':
|
||||
case 'inarray':
|
||||
$$_key = (string)$_value;
|
||||
if ($_key == 'function' || $_key == 'inarray')
|
||||
$append .= ',' . strtoupper($_key) . ",'$_value'";
|
||||
break;
|
||||
|
||||
case 'caption':
|
||||
case 'closetext':
|
||||
case 'status':
|
||||
$append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
|
||||
break;
|
||||
|
||||
case 'fgcolor':
|
||||
case 'bgcolor':
|
||||
case 'textcolor':
|
||||
case 'capcolor':
|
||||
case 'closecolor':
|
||||
case 'textfont':
|
||||
case 'captionfont':
|
||||
case 'closefont':
|
||||
case 'fgbackground':
|
||||
case 'bgbackground':
|
||||
case 'caparray':
|
||||
case 'capicon':
|
||||
case 'background':
|
||||
case 'frame':
|
||||
$append .= ',' . strtoupper($_key) . ",'$_value'";
|
||||
break;
|
||||
|
||||
case 'textsize':
|
||||
case 'captionsize':
|
||||
case 'closesize':
|
||||
case 'width':
|
||||
case 'height':
|
||||
case 'border':
|
||||
case 'offsetx':
|
||||
case 'offsety':
|
||||
case 'snapx':
|
||||
case 'snapy':
|
||||
case 'fixx':
|
||||
case 'fixy':
|
||||
case 'padx':
|
||||
case 'pady':
|
||||
case 'timeout':
|
||||
case 'delay':
|
||||
$append .= ',' . strtoupper($_key) . ",$_value";
|
||||
break;
|
||||
|
||||
case 'sticky':
|
||||
case 'left':
|
||||
case 'right':
|
||||
case 'center':
|
||||
case 'above':
|
||||
case 'below':
|
||||
case 'noclose':
|
||||
case 'autostatus':
|
||||
case 'autostatuscap':
|
||||
case 'fullhtml':
|
||||
case 'hauto':
|
||||
case 'vauto':
|
||||
case 'mouseoff':
|
||||
case 'followmouse':
|
||||
case 'closeclick':
|
||||
if ($_value) $append .= ',' . strtoupper($_key);
|
||||
break;
|
||||
|
||||
default:
|
||||
$smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($text) && !isset($inarray) && empty($function)) {
|
||||
$smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($trigger)) { $trigger = "onmouseover"; }
|
||||
|
||||
$retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
|
||||
$retval .= $append . ');"';
|
||||
if ($trigger == 'onmouseover')
|
||||
$retval .= ' onmouseout="nd();"';
|
||||
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty {popup_init} function plugin
|
||||
*
|
||||
* Type: function<br>
|
||||
* Name: popup_init<br>
|
||||
* Purpose: initialize overlib
|
||||
* @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param array
|
||||
* @param Smarty
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_popup_init($params, &$smarty)
|
||||
{
|
||||
$zindex = 1000;
|
||||
|
||||
if (!empty($params['zindex'])) {
|
||||
$zindex = $params['zindex'];
|
||||
}
|
||||
|
||||
if (!empty($params['src'])) {
|
||||
return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
|
||||
. '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
|
||||
} else {
|
||||
$smarty->trigger_error("popup_init: missing src parameter");
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,43 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsModifier
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty capitalize modifier plugin
|
||||
*
|
||||
* Type: modifier<br>
|
||||
* Name: capitalize<br>
|
||||
* Purpose: capitalize words in the string
|
||||
* @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
|
||||
* capitalize (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param string
|
||||
* @return string
|
||||
* {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
|
||||
*
|
||||
* @param string $string string to capitalize
|
||||
* @param boolean $uc_digits also capitalize "x123" to "X123"
|
||||
* @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa"
|
||||
*
|
||||
* @return string capitalized string
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
function smarty_modifier_capitalize($string, $uc_digits = false)
|
||||
function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
|
||||
{
|
||||
smarty_modifier_capitalize_ucfirst(null, $uc_digits);
|
||||
return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
|
||||
}
|
||||
|
||||
function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
|
||||
{
|
||||
static $_uc_digits = false;
|
||||
|
||||
if(isset($uc_digits)) {
|
||||
$_uc_digits = $uc_digits;
|
||||
return;
|
||||
if (Smarty::$_MBSTRING) {
|
||||
if ($lc_rest) {
|
||||
// uppercase (including hyphenated words)
|
||||
$upper_string = mb_convert_case($string, MB_CASE_TITLE, Smarty::$_CHARSET);
|
||||
} else {
|
||||
// uppercase word breaks
|
||||
$upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert_cb', $string);
|
||||
}
|
||||
// check uc_digits case
|
||||
if (!$uc_digits) {
|
||||
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($matches[1] as $match) {
|
||||
$upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
$upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert2_cb', $upper_string);
|
||||
return $upper_string;
|
||||
}
|
||||
|
||||
if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
|
||||
return ucfirst($string[0]);
|
||||
else
|
||||
return $string[0];
|
||||
|
||||
// lowercase first
|
||||
if ($lc_rest) {
|
||||
$string = strtolower($string);
|
||||
}
|
||||
// uppercase (including hyphenated words)
|
||||
$upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst_cb', $string);
|
||||
// check uc_digits case
|
||||
if (!$uc_digits) {
|
||||
if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($matches[1] as $match) {
|
||||
$upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
$upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst2_cb', $upper_string);
|
||||
return $upper_string;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Bug: create_function() use exhausts memory when used in long loops
|
||||
* Fix: use declared functions for callbacks instead of using create_function()
|
||||
* Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3
|
||||
*
|
||||
* @author Kyle Renfrow
|
||||
*/
|
||||
function smarty_mod_cap_mbconvert_cb($matches)
|
||||
{
|
||||
return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[2]), MB_CASE_UPPER, Smarty::$_CHARSET);
|
||||
}
|
||||
|
||||
?>
|
||||
function smarty_mod_cap_mbconvert2_cb($matches)
|
||||
{
|
||||
return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[3]), MB_CASE_UPPER, Smarty::$_CHARSET);
|
||||
}
|
||||
|
||||
function smarty_mod_cap_ucfirst_cb($matches)
|
||||
{
|
||||
return stripslashes($matches[1]) . ucfirst(stripslashes($matches[2]));
|
||||
}
|
||||
|
||||
function smarty_mod_cap_ucfirst2_cb($matches)
|
||||
{
|
||||
return stripslashes($matches[1]) . ucfirst(stripslashes($matches[3]));
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty cat modifier plugin
|
||||
*
|
||||
* Type: modifier<br>
|
||||
* Name: cat<br>
|
||||
* Date: Feb 24, 2003
|
||||
* Purpose: catenate a value to a variable
|
||||
* Input: string to catenate
|
||||
* Example: {$var|cat:"foo"}
|
||||
* @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
|
||||
* (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @version 1.0
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function smarty_modifier_cat($string, $cat)
|
||||
{
|
||||
return $string . $cat;
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty count_characters modifier plugin
|
||||
*
|
||||
* Type: modifier<br>
|
||||
* Name: count_characteres<br>
|
||||
* Purpose: count the number of characters in a text
|
||||
* @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
|
||||
* count_characters (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param string
|
||||
* @param boolean include whitespace in the character count
|
||||
* @return integer
|
||||
*/
|
||||
function smarty_modifier_count_characters($string, $include_spaces = false)
|
||||
{
|
||||
if ($include_spaces)
|
||||
return(strlen($string));
|
||||
|
||||
return preg_match_all("/[^\s]/",$string, $match);
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty count_paragraphs modifier plugin
|
||||
*
|
||||
* Type: modifier<br>
|
||||
* Name: count_paragraphs<br>
|
||||
* Purpose: count the number of paragraphs in a text
|
||||
* @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
|
||||
* count_paragraphs (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param string
|
||||
* @return integer
|
||||
*/
|
||||
function smarty_modifier_count_paragraphs($string)
|
||||
{
|
||||
// count \r or \n characters
|
||||
return count(preg_split('/[\r\n]+/', $string));
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty plugin
|
||||
* @package Smarty
|
||||
* @subpackage plugins
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Smarty count_sentences modifier plugin
|
||||
*
|
||||
* Type: modifier<br>
|
||||
* Name: count_sentences
|
||||
* Purpose: count the number of sentences in a text
|
||||
* @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
|
||||
* count_sentences (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @param string
|
||||
* @return integer
|
||||
*/
|
||||
function smarty_modifier_count_sentences($string)
|
||||
{
|
||||
// find periods with a word before but not after.
|
||||
return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
|
||||
}
|
||||
|
||||
/* vim: set expandtab: */
|
||||
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user