From e6b52f68378e428cee35588880a446c10d54c153 Mon Sep 17 00:00:00 2001 From: Seth Meranda <smeranda2@unl.edu> Date: Thu, 26 Nov 2009 05:02:23 +0000 Subject: [PATCH] Testing new plugins: contact importer for bringing in contacts from other social networks, friend request to make this process more natural, and riverfaces which puts the profile pic next to the river items. --- .../contact_importer/OpenInviter/LICENSE.txt | 277 +++++++ .../contact_importer/OpenInviter/POLICY.txt | 158 ++++ .../OpenInviter/autoupdate.php | 211 +++++ .../OpenInviter/conf/abv.conf | 1 + .../OpenInviter/conf/aol.conf | 1 + .../OpenInviter/conf/apropo.conf | 1 + .../OpenInviter/conf/atlas.conf | 1 + .../OpenInviter/conf/aussiemail.conf | 1 + .../OpenInviter/conf/azet.conf | 1 + .../OpenInviter/conf/badoo.conf | 1 + .../OpenInviter/conf/bebo.conf | 1 + .../OpenInviter/conf/bigstring.conf | 1 + .../OpenInviter/conf/bookcrossing.conf | 1 + .../OpenInviter/conf/bordermail.conf | 1 + .../OpenInviter/conf/brazencareerist.conf | 1 + .../OpenInviter/conf/canoe.conf | 1 + .../OpenInviter/conf/care2.conf | 1 + .../OpenInviter/conf/clevergo.conf | 1 + .../OpenInviter/conf/cyworld.conf | 1 + .../OpenInviter/conf/doramail.conf | 1 + .../OpenInviter/conf/eons.conf | 1 + .../OpenInviter/conf/evite.conf | 1 + .../OpenInviter/conf/facebook.conf | 1 + .../OpenInviter/conf/faces.conf | 1 + .../OpenInviter/conf/famiva.conf | 1 + .../OpenInviter/conf/fastmail.conf | 1 + .../OpenInviter/conf/fdcareer.conf | 1 + .../OpenInviter/conf/flickr.conf | 1 + .../OpenInviter/conf/flingr.conf | 1 + .../OpenInviter/conf/flixster.conf | 1 + .../OpenInviter/conf/fm5.conf | 1 + .../OpenInviter/conf/freemail.conf | 1 + .../OpenInviter/conf/friendfeed.conf | 1 + .../OpenInviter/conf/friendster.conf | 1 + .../OpenInviter/conf/gawab.conf | 1 + .../OpenInviter/conf/gmail.conf | 1 + .../OpenInviter/conf/gmx_net.conf | 1 + .../OpenInviter/conf/graffiti.conf | 1 + .../OpenInviter/conf/hi5.conf | 1 + .../OpenInviter/conf/hotmail.conf | 1 + .../OpenInviter/conf/hushmail.conf | 1 + .../OpenInviter/conf/hyves.conf | 1 + .../OpenInviter/conf/inbox.conf | 1 + .../OpenInviter/conf/india.conf | 1 + .../OpenInviter/conf/indiatimes.conf | 1 + .../OpenInviter/conf/inet.conf | 1 + .../OpenInviter/conf/interia.conf | 1 + .../OpenInviter/conf/katamail.conf | 1 + .../OpenInviter/conf/kids.conf | 1 + .../OpenInviter/conf/kincafe.conf | 1 + .../OpenInviter/conf/konnects.conf | 1 + .../OpenInviter/conf/koolro.conf | 1 + .../OpenInviter/conf/lastfm.conf | 1 + .../OpenInviter/conf/libero.conf | 1 + .../OpenInviter/conf/linkedin.conf | 1 + .../OpenInviter/conf/livejournal.conf | 1 + .../OpenInviter/conf/lovento.conf | 1 + .../OpenInviter/conf/lycos.conf | 1 + .../OpenInviter/conf/mail2world.conf | 1 + .../OpenInviter/conf/mail_com.conf | 1 + .../OpenInviter/conf/mail_in.conf | 1 + .../OpenInviter/conf/mail_ru.conf | 1 + .../OpenInviter/conf/meinvz.conf | 1 + .../OpenInviter/conf/meta.conf | 1 + .../OpenInviter/conf/mevio.conf | 1 + .../OpenInviter/conf/motortopia.conf | 1 + .../OpenInviter/conf/multiply.conf | 1 + .../OpenInviter/conf/mycatspace.conf | 1 + .../OpenInviter/conf/mydogspace.conf | 1 + .../OpenInviter/conf/mynet.conf | 1 + .../OpenInviter/conf/myspace.conf | 1 + .../OpenInviter/conf/netaddress.conf | 1 + .../OpenInviter/conf/netlog.conf | 1 + .../OpenInviter/conf/ning.conf | 1 + .../OpenInviter/conf/nz11.conf | 1 + .../contact_importer/OpenInviter/conf/o2.conf | 1 + .../OpenInviter/conf/operamail.conf | 1 + .../OpenInviter/conf/orkut.conf | 1 + .../OpenInviter/conf/perfspot.conf | 1 + .../OpenInviter/conf/plaxo.conf | 1 + .../OpenInviter/conf/plazes.conf | 1 + .../OpenInviter/conf/plurk.conf | 1 + .../OpenInviter/conf/pochta.conf | 1 + .../OpenInviter/conf/popstarmail.conf | 1 + .../OpenInviter/conf/rambler.conf | 1 + .../OpenInviter/conf/rediff.conf | 1 + .../OpenInviter/conf/sapo.conf | 1 + .../OpenInviter/conf/skyrock.conf | 1 + .../OpenInviter/conf/tagged.conf | 1 + .../OpenInviter/conf/techemail.conf | 1 + .../OpenInviter/conf/terra.conf | 1 + .../OpenInviter/conf/twitter.conf | 1 + .../OpenInviter/conf/twitter_ex.conf | 1 + .../OpenInviter/conf/uk2.conf | 1 + .../OpenInviter/conf/vimeo.conf | 1 + .../OpenInviter/conf/virgilio.conf | 1 + .../OpenInviter/conf/vkontakte.conf | 1 + .../OpenInviter/conf/walla.conf | 1 + .../OpenInviter/conf/web_de.conf | 1 + .../OpenInviter/conf/wpl.conf | 1 + .../OpenInviter/conf/xanga.conf | 1 + .../OpenInviter/conf/xing.conf | 1 + .../OpenInviter/conf/xuqa.conf | 1 + .../OpenInviter/conf/yahoo.conf | 1 + .../OpenInviter/conf/yandex.conf | 1 + .../OpenInviter/conf/youtube.conf | 1 + .../OpenInviter/conf/zapak.conf | 1 + .../contact_importer/OpenInviter/config.php | 19 + .../contact_importer/OpenInviter/default.php | 3 + .../contact_importer/OpenInviter/example.php | 203 +++++ .../OpenInviter/images/ers.gif | Bin 0 -> 504 bytes .../OpenInviter/images/oks.gif | Bin 0 -> 397 bytes .../contact_importer/OpenInviter/index.htm | 1 + .../contact_importer/OpenInviter/index.html | 1 + .../contact_importer/OpenInviter/index.php | 4 + .../contact_importer/OpenInviter/install.txt | 73 ++ .../OpenInviter/install_visual.pdf | Bin 0 -> 397366 bytes .../OpenInviter/openinviter.gif | Bin 0 -> 3042 bytes .../OpenInviter/openinviter.php | 491 +++++++++++ .../OpenInviter/openinviter_base.php | 716 ++++++++++++++++ .../OpenInviter/plugins/_base.php | 762 ++++++++++++++++++ .../OpenInviter/plugins/_hosted.plg.php | 118 +++ .../OpenInviter/plugins/abv.plg.php | 210 +++++ .../OpenInviter/plugins/aol.plg.php | 188 +++++ .../OpenInviter/plugins/apropo.plg.php | 185 +++++ .../OpenInviter/plugins/atlas.plg.php | 149 ++++ .../OpenInviter/plugins/aussiemail.plg.php | 160 ++++ .../OpenInviter/plugins/azet.plg.php | 146 ++++ .../OpenInviter/plugins/badoo.plg.php | 156 ++++ .../OpenInviter/plugins/bebo.plg.php | 193 +++++ .../OpenInviter/plugins/bigstring.plg.php | 135 ++++ .../OpenInviter/plugins/bookcrossing.plg.php | 171 ++++ .../OpenInviter/plugins/bordermail.plg.php | 146 ++++ .../plugins/brazencareerist.plg.php | 197 +++++ .../OpenInviter/plugins/canoe.plg.php | 179 ++++ .../OpenInviter/plugins/care2.plg.php | 188 +++++ .../OpenInviter/plugins/clevergo.plg.php | 180 +++++ .../OpenInviter/plugins/cyworld.plg.php | 212 +++++ .../OpenInviter/plugins/doramail.plg.php | 230 ++++++ .../OpenInviter/plugins/eons.plg.php | 198 +++++ .../OpenInviter/plugins/evite.plg.php | 136 ++++ .../OpenInviter/plugins/facebook.plg.php | 251 ++++++ .../OpenInviter/plugins/faces.plg.php | 173 ++++ .../OpenInviter/plugins/famiva.plg.php | 150 ++++ .../OpenInviter/plugins/fastmail.plg.php | 253 ++++++ .../OpenInviter/plugins/fdcareer.plg.php | 189 +++++ .../OpenInviter/plugins/flickr.plg.php | 210 +++++ .../OpenInviter/plugins/flingr.plg.php | 184 +++++ .../OpenInviter/plugins/flixster.plg.php | 207 +++++ .../OpenInviter/plugins/fm5.plg.php | 186 +++++ .../OpenInviter/plugins/freemail.plg.php | 148 ++++ .../OpenInviter/plugins/friendfeed.plg.php | 191 +++++ .../OpenInviter/plugins/friendster.plg.php | 208 +++++ .../OpenInviter/plugins/gawab.plg.php | 176 ++++ .../OpenInviter/plugins/gmail.plg.php | 168 ++++ .../OpenInviter/plugins/gmx_net.plg.php | 202 +++++ .../OpenInviter/plugins/graffiti.plg.php | 141 ++++ .../OpenInviter/plugins/hi5.plg.php | 206 +++++ .../OpenInviter/plugins/hotmail.plg.php | 224 +++++ .../OpenInviter/plugins/hushmail.plg.php | 152 ++++ .../OpenInviter/plugins/hyves.plg.php | 236 ++++++ .../OpenInviter/plugins/inbox.plg.php | 175 ++++ .../OpenInviter/plugins/india.plg.php | 179 ++++ .../OpenInviter/plugins/indiatimes.plg.php | 187 +++++ .../OpenInviter/plugins/inet.plg.php | 172 ++++ .../OpenInviter/plugins/interia.plg.php | 169 ++++ .../OpenInviter/plugins/katamail.plg.php | 154 ++++ .../OpenInviter/plugins/kids.plg.php | 150 ++++ .../OpenInviter/plugins/kincafe.plg.php | 125 +++ .../OpenInviter/plugins/konnects.plg.php | 204 +++++ .../OpenInviter/plugins/koolro.plg.php | 181 +++++ .../OpenInviter/plugins/lastfm.plg.php | 142 ++++ .../OpenInviter/plugins/libero.plg.php | 191 +++++ .../OpenInviter/plugins/linkedin.plg.php | 171 ++++ .../OpenInviter/plugins/livejournal.plg.php | 193 +++++ .../OpenInviter/plugins/lovento.plg.php | 181 +++++ .../OpenInviter/plugins/lycos.plg.php | 176 ++++ .../OpenInviter/plugins/mail2world.plg.php | 183 +++++ .../OpenInviter/plugins/mail_com.plg.php | 194 +++++ .../OpenInviter/plugins/mail_in.plg.php | 140 ++++ .../OpenInviter/plugins/mail_ru.plg.php | 173 ++++ .../OpenInviter/plugins/meinvz.plg.php | 202 +++++ .../OpenInviter/plugins/meta.plg.php | 172 ++++ .../OpenInviter/plugins/mevio.plg.php | 209 +++++ .../OpenInviter/plugins/motortopia.plg.php | 179 ++++ .../OpenInviter/plugins/multiply.plg.php | 192 +++++ .../OpenInviter/plugins/mycatspace.plg.php | 179 ++++ .../OpenInviter/plugins/mydogspace.plg.php | 179 ++++ .../OpenInviter/plugins/mynet.plg.php | 208 +++++ .../OpenInviter/plugins/myspace.plg.php | 200 +++++ .../OpenInviter/plugins/netaddress.plg.php | 195 +++++ .../OpenInviter/plugins/netlog.plg.php | 172 ++++ .../OpenInviter/plugins/ning.plg.php | 166 ++++ .../OpenInviter/plugins/nz11.plg.php | 150 ++++ .../OpenInviter/plugins/o2.plg.php | 174 ++++ .../OpenInviter/plugins/operamail.plg.php | 180 +++++ .../OpenInviter/plugins/orkut.plg.php | 205 +++++ .../OpenInviter/plugins/perfspot.plg.php | 209 +++++ .../OpenInviter/plugins/plaxo.plg.php | 136 ++++ .../OpenInviter/plugins/plazes.plg.php | 186 +++++ .../OpenInviter/plugins/plurk.plg.php | 181 +++++ .../OpenInviter/plugins/pochta.plg.php | 170 ++++ .../OpenInviter/plugins/popstarmail.plg.php | 182 +++++ .../OpenInviter/plugins/rambler.plg.php | 142 ++++ .../OpenInviter/plugins/rediff.plg.php | 161 ++++ .../OpenInviter/plugins/sapo.plg.php | 129 +++ .../OpenInviter/plugins/skyrock.plg.php | 206 +++++ .../OpenInviter/plugins/tagged.plg.php | 192 +++++ .../OpenInviter/plugins/techemail.plg.php | 142 ++++ .../OpenInviter/plugins/terra.plg.php | 148 ++++ .../OpenInviter/plugins/twitter_ex.plg.php | 160 ++++ .../OpenInviter/plugins/uk2.plg.php | 185 +++++ .../OpenInviter/plugins/vimeo.plg.php | 195 +++++ .../OpenInviter/plugins/virgilio.plg.php | 140 ++++ .../OpenInviter/plugins/vkontakte.plg.php | 195 +++++ .../OpenInviter/plugins/walla.plg.php | 147 ++++ .../OpenInviter/plugins/web_de.plg.php | 136 ++++ .../OpenInviter/plugins/wpl.plg.php | 157 ++++ .../OpenInviter/plugins/xanga.plg.php | 188 +++++ .../OpenInviter/plugins/xing.plg.php | 207 +++++ .../OpenInviter/plugins/xuqa.plg.php | 209 +++++ .../OpenInviter/plugins/yahoo.plg.php | 188 +++++ .../OpenInviter/plugins/yandex.plg.php | 120 +++ .../OpenInviter/plugins/youtube.plg.php | 193 +++++ .../OpenInviter/plugins/zapak.plg.php | 152 ++++ .../OpenInviter/postinstall.php.ignore | 212 +++++ .../OpenInviter/postinstall_results.res | 111 +++ .../contact_importer/OpenInviter/stats.php | 85 ++ plugins/contact_importer/ReadMe.txt | 29 + plugins/contact_importer/import.php | 322 ++++++++ plugins/contact_importer/languages/en.php | 47 ++ plugins/contact_importer/manifest.xml | 9 + plugins/contact_importer/start.php | 47 ++ plugins/friend_request/actions/approve.php | 46 ++ plugins/friend_request/actions/decline.php | 35 + .../friend_request/actions/friends/add.php | 92 +++ .../actions/friends/removefriend.php | 48 ++ plugins/friend_request/actions/revoke.php | 30 + .../graphics/icons/friendrequest.png | Bin 0 -> 685 bytes plugins/friend_request/index.php | 43 + plugins/friend_request/languages/en.php | 54 ++ plugins/friend_request/manifest.xml | 31 + plugins/friend_request/start.php | 125 +++ .../views/default/friend_request/css.php | 35 + .../views/default/friend_request/received.php | 45 ++ .../views/default/friend_request/sent.php | 43 + .../views/default/friend_request/topbar.php | 22 + plugins/riverfaces/graphics/clock_icon.gif | Bin 0 -> 1034 bytes plugins/riverfaces/languages/en.php | 16 + plugins/riverfaces/languages/es.php | 17 + plugins/riverfaces/manifest.xml | 9 + plugins/riverfaces/readme.txt | 39 + plugins/riverfaces/start.php | 18 + .../views/default/river/item/wrapper.php | 65 ++ .../views/default/riverfaces/css.php | 51 ++ .../default/settings/riverfaces/edit.php | 53 ++ 256 files changed, 23292 insertions(+) create mode 100755 plugins/contact_importer/OpenInviter/LICENSE.txt create mode 100755 plugins/contact_importer/OpenInviter/POLICY.txt create mode 100755 plugins/contact_importer/OpenInviter/autoupdate.php create mode 100755 plugins/contact_importer/OpenInviter/conf/abv.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/aol.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/apropo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/atlas.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/aussiemail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/azet.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/badoo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/bebo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/bigstring.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/bookcrossing.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/bordermail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/brazencareerist.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/canoe.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/care2.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/clevergo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/cyworld.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/doramail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/eons.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/evite.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/facebook.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/faces.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/famiva.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/fastmail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/fdcareer.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/flickr.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/flingr.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/flixster.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/fm5.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/freemail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/friendfeed.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/friendster.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/gawab.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/gmail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/gmx_net.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/graffiti.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/hi5.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/hotmail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/hushmail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/hyves.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/inbox.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/india.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/indiatimes.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/inet.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/interia.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/katamail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/kids.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/kincafe.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/konnects.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/koolro.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/lastfm.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/libero.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/linkedin.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/livejournal.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/lovento.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/lycos.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mail2world.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mail_com.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mail_in.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mail_ru.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/meinvz.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/meta.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mevio.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/motortopia.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/multiply.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mycatspace.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mydogspace.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/mynet.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/myspace.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/netaddress.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/netlog.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/ning.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/nz11.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/o2.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/operamail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/orkut.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/perfspot.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/plaxo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/plazes.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/plurk.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/pochta.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/popstarmail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/rambler.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/rediff.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/sapo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/skyrock.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/tagged.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/techemail.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/terra.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/twitter.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/twitter_ex.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/uk2.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/vimeo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/virgilio.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/vkontakte.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/walla.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/web_de.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/wpl.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/xanga.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/xing.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/xuqa.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/yahoo.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/yandex.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/youtube.conf create mode 100755 plugins/contact_importer/OpenInviter/conf/zapak.conf create mode 100755 plugins/contact_importer/OpenInviter/config.php create mode 100755 plugins/contact_importer/OpenInviter/default.php create mode 100755 plugins/contact_importer/OpenInviter/example.php create mode 100755 plugins/contact_importer/OpenInviter/images/ers.gif create mode 100755 plugins/contact_importer/OpenInviter/images/oks.gif create mode 100755 plugins/contact_importer/OpenInviter/index.htm create mode 100755 plugins/contact_importer/OpenInviter/index.html create mode 100755 plugins/contact_importer/OpenInviter/index.php create mode 100755 plugins/contact_importer/OpenInviter/install.txt create mode 100755 plugins/contact_importer/OpenInviter/install_visual.pdf create mode 100755 plugins/contact_importer/OpenInviter/openinviter.gif create mode 100755 plugins/contact_importer/OpenInviter/openinviter.php create mode 100755 plugins/contact_importer/OpenInviter/openinviter_base.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/_base.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/_hosted.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/abv.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/aol.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/apropo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/atlas.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/aussiemail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/azet.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/badoo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/bebo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/bigstring.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/bookcrossing.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/bordermail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/brazencareerist.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/canoe.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/care2.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/clevergo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/cyworld.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/doramail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/eons.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/evite.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/facebook.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/faces.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/famiva.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/fastmail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/fdcareer.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/flickr.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/flingr.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/flixster.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/fm5.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/freemail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/friendfeed.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/friendster.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/gawab.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/gmail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/gmx_net.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/graffiti.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/hi5.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/hotmail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/hushmail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/hyves.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/inbox.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/india.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/indiatimes.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/inet.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/interia.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/katamail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/kids.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/kincafe.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/konnects.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/koolro.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/lastfm.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/libero.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/linkedin.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/livejournal.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/lovento.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/lycos.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mail2world.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mail_com.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mail_in.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mail_ru.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/meinvz.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/meta.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mevio.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/motortopia.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/multiply.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mycatspace.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mydogspace.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/mynet.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/myspace.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/netaddress.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/netlog.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/ning.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/nz11.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/o2.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/operamail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/orkut.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/perfspot.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/plaxo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/plazes.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/plurk.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/pochta.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/popstarmail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/rambler.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/rediff.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/sapo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/skyrock.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/tagged.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/techemail.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/terra.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/twitter_ex.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/uk2.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/vimeo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/virgilio.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/vkontakte.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/walla.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/web_de.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/wpl.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/xanga.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/xing.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/xuqa.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/yahoo.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/yandex.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/youtube.plg.php create mode 100755 plugins/contact_importer/OpenInviter/plugins/zapak.plg.php create mode 100755 plugins/contact_importer/OpenInviter/postinstall.php.ignore create mode 100755 plugins/contact_importer/OpenInviter/postinstall_results.res create mode 100755 plugins/contact_importer/OpenInviter/stats.php create mode 100755 plugins/contact_importer/ReadMe.txt create mode 100755 plugins/contact_importer/import.php create mode 100755 plugins/contact_importer/languages/en.php create mode 100755 plugins/contact_importer/manifest.xml create mode 100755 plugins/contact_importer/start.php create mode 100755 plugins/friend_request/actions/approve.php create mode 100755 plugins/friend_request/actions/decline.php create mode 100755 plugins/friend_request/actions/friends/add.php create mode 100755 plugins/friend_request/actions/friends/removefriend.php create mode 100755 plugins/friend_request/actions/revoke.php create mode 100755 plugins/friend_request/graphics/icons/friendrequest.png create mode 100755 plugins/friend_request/index.php create mode 100755 plugins/friend_request/languages/en.php create mode 100755 plugins/friend_request/manifest.xml create mode 100755 plugins/friend_request/start.php create mode 100755 plugins/friend_request/views/default/friend_request/css.php create mode 100755 plugins/friend_request/views/default/friend_request/received.php create mode 100755 plugins/friend_request/views/default/friend_request/sent.php create mode 100755 plugins/friend_request/views/default/friend_request/topbar.php create mode 100755 plugins/riverfaces/graphics/clock_icon.gif create mode 100755 plugins/riverfaces/languages/en.php create mode 100755 plugins/riverfaces/languages/es.php create mode 100755 plugins/riverfaces/manifest.xml create mode 100755 plugins/riverfaces/readme.txt create mode 100755 plugins/riverfaces/start.php create mode 100755 plugins/riverfaces/views/default/river/item/wrapper.php create mode 100755 plugins/riverfaces/views/default/riverfaces/css.php create mode 100755 plugins/riverfaces/views/default/settings/riverfaces/edit.php diff --git a/plugins/contact_importer/OpenInviter/LICENSE.txt b/plugins/contact_importer/OpenInviter/LICENSE.txt new file mode 100755 index 00000000..0cf291b1 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/LICENSE.txt @@ -0,0 +1,277 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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. + +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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/plugins/contact_importer/OpenInviter/POLICY.txt b/plugins/contact_importer/OpenInviter/POLICY.txt new file mode 100755 index 00000000..8e1a464b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/POLICY.txt @@ -0,0 +1,158 @@ + +PRIVACY POLICY + +1. SCOPE + + 1. This website is operated by OpenInviter Limited. + + 2. OpenInviter complies with data protection legislation such as the Data + Protection Act 1998. This regulates the processing of personal data + relating to you and grants you various rights in respect of your personal + data. + + 3. The aim of this statement is to tell you how we will use any data, + including personal data, you provide through this website. Please read it + carefully before you proceed. + + +2. COLLECTION AND RETENTION OF DATA + +OpenInviter collects the following data from users of this website: + + 1. PROFILE DATA + + This is information that you provide when you register and create a profile + with OpenInviter. It includes your username and password, a contact email address + and other information that you provide during the profile set-up process. + + 2. CONFIGURATION DATA + + 1. If you have enabled the 'check for updates' setting in the OpenInviter + software, then OpenInviter will collect information relating to the configuration + of your server used to run OpenInviter. This information is used to identify + which product update alerts are relevant to you and to profile the + community so that we can focus development and testing efforts on common + inviter configurations. This configuration data includes: + + 1. the version and basic configuration options of the inviter; and + 2. type and version information about other software which OpenInviter + depends on, including: the webserver, PHP and MySQL. + + 3. WEBSITE DATA + + 1. OpenInviter collects data regarding anonymous visitors to the OpenInviter website + including the following: + 1. the IP address of the user's computer (which may include a domain name); + 2. the referring URL (if any); and + 3. details of the Internet browser software used by the user to view + the OpenInviter website. + 2. Further, if you use the online "Contact us" feature of the website, + we collect your name, email address and details of your message to + enable us to respond to your inquiry. + + +3. HOW WE USE YOUR PERSONAL INFORMATION AND WITH WHOM WE SHARE YOUR INFORMATION + + 1. We use your personal information to manage your online profile, send you + details of software updates and other general communications. If you have + indicated that you wish to receive such information, then we may also send + you information about new products and/or services that OpenInviter provides. You + can opt-out of receiving future marketing material by changing the relevant + setting in your OpenInviter profile or by contacting us via our online contact + form. + + 2. We will employ the services of third parties to help us in certain + areas, such as website hosting. In these cases, the third party will + receive your information, for which you must provide your consent by + ticking the consent box after you have read this Privacy Policy. However, + at all times, we will control and be responsible for the use of your + information. + + +4. TRANSFER OF YOUR INFORMATION OUTSIDE EUROPE + +The hosted version of the OpenInviter software is hosted by a third party located in +the United States of America. If OpenInviter provides you with the hosted version, +we may transfer some of your information to this third party. By submitting +your information to this website in order to receive the hosted version and by +ticking the consent box after having read this Privacy Policy, you consent to +such transfers taking place. + + +5. COOKIES + + 1. A cookie is a text-only string of information that a website transfers + to the cookie file of your computer's hard disk. A cookie will typically + contain the name of the domain from which the cookie has come, the + 'lifetime' of the cookie, and a value, usually a randomly generated unique + number. + + + 2. When you visit our website we send you a cookie. We use cookies to + identify you as a valid OpenInviter user, to ensure that no one else can + simultaneously log in and use your OpenInviter profile and to help you + personalise your OpenInviter experience in conjunction with your OpenInviter profile. + + 3. For more information about how cookies work and how to disable them, go + to http://www.allaboutcookies.org/manage-cookies/ . However, if you choose + to disable cookies, you will not be able to enjoy a significant portion of + the OpenInviter website and software functionality. + + +6. LINKS + +Our site contains links to other web sites over which we have no control. We +are not responsible for privacy policies or practices of other websites to +which you choose to link from this site. We encourage you to review the +privacy policies of those other web sites so that you can understand how they +collect, use and share your information. + + +7. SECURITY + +We have implemented reasonable technical and organisational measures designed +to secure your personal information from accidental loss and from unauthorised +access, use, alteration or disclosure. However, the Internet is an open system +and we cannot guarantee that unauthorised third parties will never be able to +defeat those measures or use your personal information for improper purposes. + + +8. SALE OF THE BUSINESS + +In the event that the business is sold or integrated with another business, +your details will be disclosed to our advisers and any prospective purchaser's +adviser and will be passed to the new owners of the business. + + +9. YOUR RIGHT TO ACCESS INFORMATION + +You are entitled to see the information held about you. If you wish to do +this, please contact us via our online contact form . We may require you to +provide verification of your identity to provide a copy of the information we hold. +We will respond to any request in accordance with the current data protection +legislation and in any event within 40 days of receipt a valid request. Please +note that in certain circumstances we may withhold access to your information +where we have the right to do so under current data protection legislation. + + +10. UPDATING YOUR INFORMATION + +You may review, correct, update or change your personal information at any +time by changing the relevant setting in your OpenInviter profile or by contacting +us via our online contact form . + + +11. CHANGES TO THIS PRIVACY POLICY + +If our privacy policy changes in any way, we will place an updated version on +this page. Regularly reviewing this page ensures that you are always aware of +what information we collect, how we use it and under what circumstances, if +any, we will share it with other parties. + + +CONTACTING US + +If you have any questions about this statement or your personal information, +please contact us via our online contact form or by emailing us at +hello@OpenInviter.com + diff --git a/plugins/contact_importer/OpenInviter/autoupdate.php b/plugins/contact_importer/OpenInviter/autoupdate.php new file mode 100755 index 00000000..31aae3eb --- /dev/null +++ b/plugins/contact_importer/OpenInviter/autoupdate.php @@ -0,0 +1,211 @@ +<?php +set_time_limit(0); +if (!is_writable(dirname(__FILE__))) { echo "<b>OpenInviter</b> folder is not writable. Updates will not be posible<br>";exit; } +if (!is_writable(dirname(__FILE__).'/plugins')) { echo "<b>OpenInviter/plugins</b> folder is not writable. Updates will not be posible<br>";exit; } +if (file_exists(dirname(__FILE__)."/postinstall.php")) { echo "Delete <b>postinstall.php</b> before running the autoupdater";exit; } +include(dirname(__FILE__).'/openinviter.php'); +$inviter=new openinviter(); +class update extends openinviter_base + { + public $plugins; + + public $settings; + + protected $timeout=30; + + public function makeUpdate() + { + $xml=$this->checkVersions(); + if (!empty($xml)) + { + $update_files=$this->parseXmlUpdates($xml); + $update=true;$newFiles=array(); + foreach($update_files as $name_file=>$arrayfile) + if ($arrayfile['type']=='new') + { + if(!empty($this->settings['update_files'])) + { + if (isset($this->plugins[$arrayfile['plugin_type']][$name_file])) + { + if (!empty($this->plugins[$arrayfile['plugin_type']][$name_file]['autoupdate'])) $newFiles[$name_file]=array('sum'=>$arrayfile['sum'],'plugin_type'=>$arrayfile['plugin_type']); + elseif($arrayfile['plugin_type']=='base') $newFiles[$name_file]=array('sum'=>$arrayfile['sum'],'plugin_type'=>$arrayfile['plugin_type']); + } + } + else + { + if($arrayfile['plugin_type']=='base') $newFiles[$name_file]=array('sum'=>$arrayfile['sum'],'plugin_type'=>$arrayfile['plugin_type']); + else $newFiles[$name_file]=array('sum'=>$arrayfile['sum'],'plugin_type'=>$arrayfile['plugin_type']); + } + } + + foreach ($newFiles as $name_file=>$arrayFile) + { + $headers=array('Content-Type'=>'application/xml','X_USER'=>$this->settings['username'],'X_SIGNATURE'=>$this->makeSignature($this->settings['private_key'],$this->xmlFile($name_file))); + $res=$this->getNewFile(gzcompress($this->xmlFile($name_file),9),$headers); + if (!empty($res)) + { + $fileDeCmp=gzuncompress($res);$elementsDownload=$this->getElementsDownload($fileDeCmp); + $file_content=$elementsDownload['fileStrip'];$signatureBulk=$elementsDownload['signatureBulk']; + $this->verifySignature($signatureBulk,$file_content); + if ($arrayFile['sum']!=md5($file_content)) $update=false; + elseif (!file_put_contents($this->getUpdateFilePath($name_file).".tmp",$file_content)) $this->ers("Unable to write new updates"); + } + else $update=false; + } + if ($update) + { + foreach($newFiles as $name_file=>$arrayfile) + { + file_put_contents($this->getUpdateFilePath($name_file),file_get_contents($this->getUpdateFilePath($name_file).".tmp")); + unlink($this->getUpdateFilePath($name_file).".tmp"); + $this->writeConf($name_file,$arrayfile['plugin_type']); + } + $this->array2Log($update_files); + } + else + { + foreach($newFiles as $name_file=>$arrayfile) if (file_exists($this->getUpdateFilePath($name_file).".tmp")) unlink($this->getUpdateFilePath($name_file).".tmp"); + if (!$update) $this->ers("Unable to download updates"); + } + } + else $this->ers("Unable to connect to Server"); + } + + public function writeConf($name_file,$type=false) + { + if (!file_exists(dirname(__FILE__)."/conf")) mkdir(dirname(__FILE__)."/conf",0755,true); + if ($type=='social') { if (!file_exists(dirname(__FILE__)."/conf/{$name_file}.conf")) file_put_contents(dirname(__FILE__)."/conf/{$name_file}.conf",'<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?>'); } + elseif($type=='email') { if (!file_exists(dirname(__FILE__)."/conf/{$name_file}.conf")) file_put_contents(dirname(__FILE__)."/conf/{$name_file}.conf",'<?php $enable=true;$autoUpdate=true; ?>'); } + } + + private function verifySignature($signatureBulk,$fileContent) + { + if (strpos($signatureBulk,'X_SIGNATURE:')===false) $this->ers("INVALID SIGNATURE"); + else + { + $start=strpos($signatureBulk,'X_SIGNATURE:')+strlen('X_SIGNATURE:');$end=strlen($signatureBulk); + $signature=trim(substr($signatureBulk,$start,$end-$start)); + $signature_check=$this->makeSignature($this->settings['private_key'],$fileContent); + if($signature!=$signature_check) $this->ers("Invalid SIGNATURE"); + else return true; + } + } + + public function getElementsDownload($res) + { + $start=0;$end=strpos($res,"<?");$signatureBulk=trim(substr($res,$start,$end));$fileStriped=str_replace($signatureBulk,'',$res); + if (empty($signatureBulk)) $this->ers("Invalid Signature"); + if (empty($fileStriped)) $this->ers("Unable to download"); + return array('signatureBulk'=>$signatureBulk,'fileStrip'=>$fileStriped); + } + + protected function getUpdateFilePath($plugin) + { + if ($plugin=='openinviter') return dirname(__FILE__)."/{$plugin}.php"; + elseif($plugin=='_base') return dirname(__FILE__)."/plugins/{$plugin}.php"; + else return dirname(__FILE__)."/plugins/{$plugin}.plg.php"; + } + + public function xmlFile($file_name) + { + return "<request><api_version>1.8</api_version><file>{$file_name}</file></request>"; + } + + public function xmlVersions() + { + $xml="<request><api_version>1.8</api_version><services>"; + if (!empty($this->plugins)) + foreach ($this->plugins as $type=>$dummy) + foreach ($dummy as $plugin=>$details) + $xml.="<service name='{$details['name']}'> + <version>{$details['version']}</version> + </service>"; + else $xml.="<service name=''> + <version></version> + </service> + "; + return $xml.="</services></request>"; + } + + public function checkVersions() + { + $this->init(); + $xml=$this->xmlVersions(); + $headers=array('Content-Type'=>'application/xml','X_USER'=>$this->settings['username'],'X_SIGNATURE'=>$this->makeSignature($this->settings['private_key'],$xml)); + $res=gzuncompress($this->post("http://openinviter.com/service_download.php",gzcompress($xml,9),false,false,false,$headers,true)); + $this->stopPlugin(); + if ((empty($res))) $this->ers("Unable to Connect to Server"); + elseif (strpos($res,'<error>')!==false) {$res=str_replace("<error>","",str_replace("</error>","",$res));$this->ers($res);} + return $res; + } + + public function parseXmlUpdates($xml) + { + $versions=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($xml)) $doc->loadHTML($xml);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//service";$data=$xpath->query($query); + foreach($data as $node) $versions[(string)$node->childNodes->item(0)->nodeValue]=array('type'=>(string)$node->childNodes->item(2)->nodeValue,'sum'=>(string)$node->childNodes->item(1)->nodeValue,'plugin_type'=>(string)$node->childNodes->item(3)->nodeValue); + return $versions; + } + + public function getNewFile($xml,$headers) + { + $this->init(); + $res=$this->post("http://openinviter.com/service_download.php",$xml,false,false,false,$headers,true); + $this->stopPlugin(); + return $res; + } + + private function makeSignature($var1,$var2) + { + return md5(md5($var1).md5($var2)); + } + + private function array2Log($array) + { + $date=date("Y-m-d H:i:s");$updateCount=0; + $string="[$date] UPDATE STARTED\r\n"; + foreach($array as $key=>$values) if ($values['type']=='new') { $string.="\tUPDATED: {$key}.php\r\n";$updateCount++; } + $string.="\tUPDATE DONE. {$updateCount} FILES UPDATED\r\n"; + $this->writeLog($string); + } + + public function ers($contents) + { + $string="[".date("Y-m-d H:i:s")."] ERROR ".$contents."\r\n"; + $this->writeLog($string); + echo $string; + exit; + } + + public function writeLog($contents) + { + $fp=fopen($this->settings['cookie_path'].'/oi_update_log.txt','a+');if ($fp) { fwrite($fp,$contents);fclose($fp); } + } + + public function login($user,$pass) + { + return; + } + + public function getMyContacts() + { + return; + } + + public function logout() + { + return; + } + + } +$plugins=$inviter->getPlugins(true); +$files_base['base']=array('openinviter'=>array('name'=>'openinviter','version'=>$inviter->getVersion()),'_base'=>array('name'=>'_base','version'=>$inviter->getVersion())); +$update=new update(); +$update->settings=$inviter->settings; +$update->plugins=(!empty($plugins)?array_merge($files_base,$plugins):$files_base); +$update->service_user='updater'; +$update->service_pass='updater'; +$update->service='updater'; +$update->makeUpdate(); +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/abv.conf b/plugins/contact_importer/OpenInviter/conf/abv.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/abv.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/aol.conf b/plugins/contact_importer/OpenInviter/conf/aol.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/aol.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/apropo.conf b/plugins/contact_importer/OpenInviter/conf/apropo.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/apropo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/atlas.conf b/plugins/contact_importer/OpenInviter/conf/atlas.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/atlas.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/aussiemail.conf b/plugins/contact_importer/OpenInviter/conf/aussiemail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/aussiemail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/azet.conf b/plugins/contact_importer/OpenInviter/conf/azet.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/azet.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/badoo.conf b/plugins/contact_importer/OpenInviter/conf/badoo.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/badoo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/bebo.conf b/plugins/contact_importer/OpenInviter/conf/bebo.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/bebo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/bigstring.conf b/plugins/contact_importer/OpenInviter/conf/bigstring.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/bigstring.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/bookcrossing.conf b/plugins/contact_importer/OpenInviter/conf/bookcrossing.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/bookcrossing.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/bordermail.conf b/plugins/contact_importer/OpenInviter/conf/bordermail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/bordermail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/brazencareerist.conf b/plugins/contact_importer/OpenInviter/conf/brazencareerist.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/brazencareerist.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/canoe.conf b/plugins/contact_importer/OpenInviter/conf/canoe.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/canoe.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/care2.conf b/plugins/contact_importer/OpenInviter/conf/care2.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/care2.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/clevergo.conf b/plugins/contact_importer/OpenInviter/conf/clevergo.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/clevergo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/cyworld.conf b/plugins/contact_importer/OpenInviter/conf/cyworld.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/cyworld.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/doramail.conf b/plugins/contact_importer/OpenInviter/conf/doramail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/doramail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/eons.conf b/plugins/contact_importer/OpenInviter/conf/eons.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/eons.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/evite.conf b/plugins/contact_importer/OpenInviter/conf/evite.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/evite.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/facebook.conf b/plugins/contact_importer/OpenInviter/conf/facebook.conf new file mode 100755 index 00000000..0220fa88 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/facebook.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=2;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/faces.conf b/plugins/contact_importer/OpenInviter/conf/faces.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/faces.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/famiva.conf b/plugins/contact_importer/OpenInviter/conf/famiva.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/famiva.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/fastmail.conf b/plugins/contact_importer/OpenInviter/conf/fastmail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/fastmail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/fdcareer.conf b/plugins/contact_importer/OpenInviter/conf/fdcareer.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/fdcareer.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/flickr.conf b/plugins/contact_importer/OpenInviter/conf/flickr.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/flickr.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/flingr.conf b/plugins/contact_importer/OpenInviter/conf/flingr.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/flingr.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/flixster.conf b/plugins/contact_importer/OpenInviter/conf/flixster.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/flixster.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/fm5.conf b/plugins/contact_importer/OpenInviter/conf/fm5.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/fm5.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/freemail.conf b/plugins/contact_importer/OpenInviter/conf/freemail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/freemail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/friendfeed.conf b/plugins/contact_importer/OpenInviter/conf/friendfeed.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/friendfeed.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/friendster.conf b/plugins/contact_importer/OpenInviter/conf/friendster.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/friendster.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/gawab.conf b/plugins/contact_importer/OpenInviter/conf/gawab.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/gawab.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/gmail.conf b/plugins/contact_importer/OpenInviter/conf/gmail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/gmail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/gmx_net.conf b/plugins/contact_importer/OpenInviter/conf/gmx_net.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/gmx_net.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/graffiti.conf b/plugins/contact_importer/OpenInviter/conf/graffiti.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/graffiti.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/hi5.conf b/plugins/contact_importer/OpenInviter/conf/hi5.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/hi5.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/hotmail.conf b/plugins/contact_importer/OpenInviter/conf/hotmail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/hotmail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/hushmail.conf b/plugins/contact_importer/OpenInviter/conf/hushmail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/hushmail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/hyves.conf b/plugins/contact_importer/OpenInviter/conf/hyves.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/hyves.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/inbox.conf b/plugins/contact_importer/OpenInviter/conf/inbox.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/inbox.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/india.conf b/plugins/contact_importer/OpenInviter/conf/india.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/india.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/indiatimes.conf b/plugins/contact_importer/OpenInviter/conf/indiatimes.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/indiatimes.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/inet.conf b/plugins/contact_importer/OpenInviter/conf/inet.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/inet.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/interia.conf b/plugins/contact_importer/OpenInviter/conf/interia.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/interia.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/katamail.conf b/plugins/contact_importer/OpenInviter/conf/katamail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/katamail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/kids.conf b/plugins/contact_importer/OpenInviter/conf/kids.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/kids.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/kincafe.conf b/plugins/contact_importer/OpenInviter/conf/kincafe.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/kincafe.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/konnects.conf b/plugins/contact_importer/OpenInviter/conf/konnects.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/konnects.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/koolro.conf b/plugins/contact_importer/OpenInviter/conf/koolro.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/koolro.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/lastfm.conf b/plugins/contact_importer/OpenInviter/conf/lastfm.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/lastfm.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/libero.conf b/plugins/contact_importer/OpenInviter/conf/libero.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/libero.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/linkedin.conf b/plugins/contact_importer/OpenInviter/conf/linkedin.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/linkedin.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/livejournal.conf b/plugins/contact_importer/OpenInviter/conf/livejournal.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/livejournal.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/lovento.conf b/plugins/contact_importer/OpenInviter/conf/lovento.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/lovento.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/lycos.conf b/plugins/contact_importer/OpenInviter/conf/lycos.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/lycos.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mail2world.conf b/plugins/contact_importer/OpenInviter/conf/mail2world.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mail2world.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mail_com.conf b/plugins/contact_importer/OpenInviter/conf/mail_com.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mail_com.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mail_in.conf b/plugins/contact_importer/OpenInviter/conf/mail_in.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mail_in.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mail_ru.conf b/plugins/contact_importer/OpenInviter/conf/mail_ru.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mail_ru.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/meinvz.conf b/plugins/contact_importer/OpenInviter/conf/meinvz.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/meinvz.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/meta.conf b/plugins/contact_importer/OpenInviter/conf/meta.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/meta.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mevio.conf b/plugins/contact_importer/OpenInviter/conf/mevio.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mevio.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/motortopia.conf b/plugins/contact_importer/OpenInviter/conf/motortopia.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/motortopia.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/multiply.conf b/plugins/contact_importer/OpenInviter/conf/multiply.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/multiply.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mycatspace.conf b/plugins/contact_importer/OpenInviter/conf/mycatspace.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mycatspace.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mydogspace.conf b/plugins/contact_importer/OpenInviter/conf/mydogspace.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mydogspace.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/mynet.conf b/plugins/contact_importer/OpenInviter/conf/mynet.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/mynet.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/myspace.conf b/plugins/contact_importer/OpenInviter/conf/myspace.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/myspace.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/netaddress.conf b/plugins/contact_importer/OpenInviter/conf/netaddress.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/netaddress.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/netlog.conf b/plugins/contact_importer/OpenInviter/conf/netlog.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/netlog.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/ning.conf b/plugins/contact_importer/OpenInviter/conf/ning.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/ning.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/nz11.conf b/plugins/contact_importer/OpenInviter/conf/nz11.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/nz11.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/o2.conf b/plugins/contact_importer/OpenInviter/conf/o2.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/o2.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/operamail.conf b/plugins/contact_importer/OpenInviter/conf/operamail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/operamail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/orkut.conf b/plugins/contact_importer/OpenInviter/conf/orkut.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/orkut.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/perfspot.conf b/plugins/contact_importer/OpenInviter/conf/perfspot.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/perfspot.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/plaxo.conf b/plugins/contact_importer/OpenInviter/conf/plaxo.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/plaxo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/plazes.conf b/plugins/contact_importer/OpenInviter/conf/plazes.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/plazes.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/plurk.conf b/plugins/contact_importer/OpenInviter/conf/plurk.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/plurk.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/pochta.conf b/plugins/contact_importer/OpenInviter/conf/pochta.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/pochta.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/popstarmail.conf b/plugins/contact_importer/OpenInviter/conf/popstarmail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/popstarmail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/rambler.conf b/plugins/contact_importer/OpenInviter/conf/rambler.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/rambler.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/rediff.conf b/plugins/contact_importer/OpenInviter/conf/rediff.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/rediff.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/sapo.conf b/plugins/contact_importer/OpenInviter/conf/sapo.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/sapo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/skyrock.conf b/plugins/contact_importer/OpenInviter/conf/skyrock.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/skyrock.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/tagged.conf b/plugins/contact_importer/OpenInviter/conf/tagged.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/tagged.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/techemail.conf b/plugins/contact_importer/OpenInviter/conf/techemail.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/techemail.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/terra.conf b/plugins/contact_importer/OpenInviter/conf/terra.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/terra.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/twitter.conf b/plugins/contact_importer/OpenInviter/conf/twitter.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/twitter.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/twitter_ex.conf b/plugins/contact_importer/OpenInviter/conf/twitter_ex.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/twitter_ex.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/uk2.conf b/plugins/contact_importer/OpenInviter/conf/uk2.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/uk2.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/vimeo.conf b/plugins/contact_importer/OpenInviter/conf/vimeo.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/vimeo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/virgilio.conf b/plugins/contact_importer/OpenInviter/conf/virgilio.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/virgilio.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/vkontakte.conf b/plugins/contact_importer/OpenInviter/conf/vkontakte.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/vkontakte.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/walla.conf b/plugins/contact_importer/OpenInviter/conf/walla.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/walla.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/web_de.conf b/plugins/contact_importer/OpenInviter/conf/web_de.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/web_de.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/wpl.conf b/plugins/contact_importer/OpenInviter/conf/wpl.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/wpl.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/xanga.conf b/plugins/contact_importer/OpenInviter/conf/xanga.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/xanga.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/xing.conf b/plugins/contact_importer/OpenInviter/conf/xing.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/xing.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/xuqa.conf b/plugins/contact_importer/OpenInviter/conf/xuqa.conf new file mode 100755 index 00000000..f35a15c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/xuqa.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/yahoo.conf b/plugins/contact_importer/OpenInviter/conf/yahoo.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/yahoo.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/yandex.conf b/plugins/contact_importer/OpenInviter/conf/yandex.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/yandex.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/youtube.conf b/plugins/contact_importer/OpenInviter/conf/youtube.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/youtube.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/conf/zapak.conf b/plugins/contact_importer/OpenInviter/conf/zapak.conf new file mode 100755 index 00000000..dc0f892b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/conf/zapak.conf @@ -0,0 +1 @@ +<?php $enable=true;$autoUpdate=true; ?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/config.php b/plugins/contact_importer/OpenInviter/config.php new file mode 100755 index 00000000..528675c0 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/config.php @@ -0,0 +1,19 @@ +<?php +$openinviter_settings=array( +'username'=>"pjuvekar", +'private_key'=>"a72c5cff8f92dab96232502e105e60fd", +'cookie_path'=>"/tmp", +'message_body'=>"You are invited to ...", +'message_subject'=>" is inviting you to ...", +'transport'=>"curl", +'local_debug'=>"on_error", +'remote_debug'=>false, +'plugins_cache_time'=>"1800", +'update_files'=>true, +'hosted'=>false, +'proxies'=>array(), +'stats'=>false, +'stats_user'=>"", +'stats_password'=>"" +); +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/default.php b/plugins/contact_importer/OpenInviter/default.php new file mode 100755 index 00000000..6e024a1a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/default.php @@ -0,0 +1,3 @@ +<?php +echo "OpenInviter - import addressbook/contacts from different email providers like Yahoo, Gmail, Hotmail, Live etc. using different CMS software like Drupal, Joomla etc. or forum software like PHPBB, SMF etc. available at <a href='openinviter.com'>http://openinviter.com</a>"; +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/example.php b/plugins/contact_importer/OpenInviter/example.php new file mode 100755 index 00000000..de0a64eb --- /dev/null +++ b/plugins/contact_importer/OpenInviter/example.php @@ -0,0 +1,203 @@ +<?php +include('openinviter.php'); +$inviter=new OpenInviter(); +$oi_services=$inviter->getPlugins(); +if (isset($_POST['provider_box'])) +{ + if (isset($oi_services['email'][$_POST['provider_box']])) $plugType='email'; + elseif (isset($oi_services['social'][$_POST['provider_box']])) $plugType='social'; + else $plugType=''; +} +else $plugType = ''; +function ers($ers) + { + if (!empty($ers)) + { + $contents="<table cellspacing='0' cellpadding='0' style='border:1px solid red;' align='center'><tr><td valign='middle' style='padding:3px' valign='middle'><img src='images/ers.gif'></td><td valign='middle' style='color:red;padding:5px;'>"; + foreach ($ers as $key=>$error) + $contents.="{$error}<br >"; + $contents.="</td></tr></table><br >"; + return $contents; + } + } + +function oks($oks) + { + if (!empty($oks)) + { + $contents="<table border='0' cellspacing='0' cellpadding='10' style='border:1px solid #5897FE;' align='center'><tr><td valign='middle' valign='middle'><img src='images/oks.gif' ></td><td valign='middle' style='color:#5897FE;padding:5px;'> "; + foreach ($oks as $key=>$msg) + $contents.="{$msg}<br >"; + $contents.="</td></tr></table><br >"; + return $contents; + } + } + +if (!empty($_POST['step'])) $step=$_POST['step']; +else $step='get_contacts'; + +$ers=array();$oks=array();$import_ok=false;$done=false; +if ($_SERVER['REQUEST_METHOD']=='POST') + { + if ($step=='get_contacts') + { + if (empty($_POST['email_box'])) + $ers['email']="Email missing !"; + if (empty($_POST['password_box'])) + $ers['password']="Password missing !"; + if (empty($_POST['provider_box'])) + $ers['provider']="Provider missing !"; + if (count($ers)==0) + { + $inviter->startPlugin($_POST['provider_box']); + $internal=$inviter->getInternalError(); + if ($internal) + $ers['inviter']=$internal; + elseif (!$inviter->login($_POST['email_box'],$_POST['password_box'])) + { + $internal=$inviter->getInternalError(); + $ers['login']=($internal?$internal:"Login failed. Please check the email and password you have provided and try again later !"); + } + elseif (false===$contacts=$inviter->getMyContacts()) + $ers['contacts']="Unable to get contacts !"; + else + { + $import_ok=true; + $step='send_invites'; + $_POST['oi_session_id']=$inviter->plugin->getSessionID(); + $_POST['message_box']=''; + } + } + } + elseif ($step=='send_invites') + { + if (empty($_POST['provider_box'])) $ers['provider']='Provider missing !'; + else + { + $inviter->startPlugin($_POST['provider_box']); + $internal=$inviter->getInternalError(); + if ($internal) $ers['internal']=$internal; + else + { + if (empty($_POST['email_box'])) $ers['inviter']='Inviter information missing !'; + if (empty($_POST['oi_session_id'])) $ers['session_id']='No active session !'; + if (empty($_POST['message_box'])) $ers['message_body']='Message missing !'; + else $_POST['message_box']=strip_tags($_POST['message_box']); + $selected_contacts=array();$contacts=array(); + $message=array('subject'=>$inviter->settings['message_subject'],'body'=>$inviter->settings['message_body'],'attachment'=>"\n\rAttached message: \n\r".$_POST['message_box']); + if ($inviter->showContacts()) + { + foreach ($_POST as $key=>$val) + if (strpos($key,'check_')!==false) + $selected_contacts[$_POST['email_'.$val]]=$_POST['name_'.$val]; + elseif (strpos($key,'email_')!==false) + { + $temp=explode('_',$key);$counter=$temp[1]; + if (is_numeric($temp[1])) $contacts[$val]=$_POST['name_'.$temp[1]]; + } + if (count($selected_contacts)==0) $ers['contacts']="You haven't selected any contacts to invite !"; + } + } + } + if (count($ers)==0) + { + $sendMessage=$inviter->sendMessage($_POST['oi_session_id'],$message,$selected_contacts); + $inviter->logout(); + if ($sendMessage===-1) + { + $message_footer="\r\n\r\nThis invite was sent using OpenInviter technology."; + $message_subject=$_POST['email_box'].$message['subject']; + $message_body=$message['body'].$message['attachment'].$message_footer; + $headers="From: {$_POST['email_box']}"; + foreach ($selected_contacts as $email=>$name) + mail($email,$message_subject,$message_body,$headers); + $oks['mails']="Mails sent successfully"; + } + elseif ($sendMessage===false) + { + $internal=$inviter->getInternalError(); + $ers['internal']=($internal?$internal:"There were errors while sending your invites.<br>Please try again later!"); + } + else $oks['internal']="Invites sent successfully!"; + $done=true; + } + } + } +else + { + $_POST['email_box']=''; + $_POST['password_box']=''; + $_POST['provider_box']=''; + } + +$contents="<script type='text/javascript'> + function toggleAll(element) + { + var form = document.forms.openinviter, z = 0; + for(z=0; z<form.length;z++) + { + if(form[z].type == 'checkbox') + form[z].checked = element.checked; + } + } +</script>"; +$contents.="<form action='' method='POST' name='openinviter'>".ers($ers).oks($oks); +if (!$done) + { + if ($step=='get_contacts') + { + $contents.="<table align='center' class='thTable' cellspacing='2' cellpadding='0' style='border:none;'> + <tr class='thTableRow'><td align='right'><label for='email_box'>Email</label></td><td><input class='thTextbox' type='text' name='email_box' value='{$_POST['email_box']}'></td></tr> + <tr class='thTableRow'><td align='right'><label for='password_box'>Password</label></td><td><input class='thTextbox' type='password' name='password_box' value='{$_POST['password_box']}'></td></tr> + <tr class='thTableRow'><td align='right'><label for='provider_box'>Email provider</label></td><td><select class='thSelect' name='provider_box'><option value=''></option>"; + foreach ($oi_services as $type=>$providers) + { + $contents.="<optgroup label='{$inviter->pluginTypes[$type]}'>"; + foreach ($providers as $provider=>$details) + $contents.="<option value='{$provider}'".($_POST['provider_box']==$provider?' selected':'').">{$details['name']}</option>"; + $contents.="</optgroup>"; + } + $contents.="</select></td></tr> + <tr class='thTableImportantRow'><td colspan='2' align='center'><input class='thButton' type='submit' name='import' value='Import Contacts'></td></tr> + </table><input type='hidden' name='step' value='get_contacts'>"; + } + else + $contents.="<table class='thTable' cellspacing='0' cellpadding='0' style='border:none;'> + <tr class='thTableRow'><td align='right' valign='top'><label for='message_box'>Message</label></td><td><textarea rows='5' cols='50' name='message_box' class='thTextArea' style='width:300px;'>{$_POST['message_box']}</textarea></td></tr> + <tr class='thTableRow'><td align='center' colspan='2'><input type='submit' name='send' value='Send Invites' class='thButton' ></td></tr> + </table>"; + } +$contents.="<center><a href='http://openinviter.com/'><img src='http://openinviter.com/images/banners/banner_blue_1.gif' border='0' alt='Powered by OpenInviter.com' title='Powered by OpenInviter.com'></a></center>"; +if (!$done) + { + if ($step=='send_invites') + { + if ($inviter->showContacts()) + { + $contents.="<table class='thTable' align='center' cellspacing='0' cellpadding='0'><tr class='thTableHeader'><td colspan='".($plugType=='email'? "3":"2")."'>Your contacts</td></tr>"; + if (count($contacts)==0) + $contents.="<tr class='thTableOddRow'><td align='center' style='padding:20px;' colspan='".($plugType=='email'? "3":"2")."'>You do not have any contacts in your address book.</td></tr>"; + else + { + $contents.="<tr class='thTableDesc'><td><input type='checkbox' onChange='toggleAll(this)' name='toggle_all' title='Select/Deselect all' checked>Invite?</td><td>Name</td>".($plugType == 'email' ?"<td>E-mail</td>":"")."</tr>"; + $odd=true;$counter=0; + foreach ($contacts as $email=>$name) + { + $counter++; + if ($odd) $class='thTableOddRow'; else $class='thTableEvenRow'; + $contents.="<tr class='{$class}'><td><input name='check_{$counter}' value='{$counter}' type='checkbox' class='thCheckbox' checked><input type='hidden' name='email_{$counter}' value='{$email}'><input type='hidden' name='name_{$counter}' value='{$name}'></td><td>{$name}</td>".($plugType == 'email' ?"<td>{$email}</td>":"")."</tr>"; + $odd=!$odd; + } + $contents.="<tr class='thTableFooter'><td colspan='".($plugType=='email'? "3":"2")."' style='padding:3px;'><input type='submit' name='send' value='Send invites' class='thButton'></td></tr>"; + } + $contents.="</table>"; + } + $contents.="<input type='hidden' name='step' value='send_invites'> + <input type='hidden' name='provider_box' value='{$_POST['provider_box']}'> + <input type='hidden' name='email_box' value='{$_POST['email_box']}'> + <input type='hidden' name='oi_session_id' value='{$_POST['oi_session_id']}'>"; + } + } +$contents.="</form>"; +echo $contents; +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/images/ers.gif b/plugins/contact_importer/OpenInviter/images/ers.gif new file mode 100755 index 0000000000000000000000000000000000000000..44e59984ea43d9f3672138501144aa27beb0d62f GIT binary patch literal 504 zcmZ?wbhEHblwpu#xN5}k|Mcm9sj2@aO!$|O@Gn08|IVHNl9K*!+48Tb=wEvJ{~bI2 zm6iRAiu!-z#J`l3f6>wZCQbTRQu436``^^5|5vU0zh=$9zP|r^_WVC^;QyjU|2jMW z<>dU!&;M6g_<!BHf3dOumn`{LQ}b`ejQ`uV{a?QPUt8P1>C^w8J^Qb>_g_ZF|CKBM zO`iP!)Tw_hE&rD;{ny<5ud(r8M8yC9{~3q_ia%Kx85oQhbU?~Meqvzz?=Z8#Lr1Fr z#FC<uIYQi$yh_u$BJ|EJ)DnDMwYROS_@i#Upm)Pz>kT1N4Q`IcAK3g(HrR3|mhgH6 z$18bq@yBwziNqPi$$7HI>A7YbY8&as@=JIM$8x%`$FevJ)_bwUaybjdGP%SUN_#TJ z3OLKIa?z2GRrFY7DC4}+kinI;&TzdO!(!(+cgZ*f_lr(PkGpBa^02y|Gh}v_iDmat zjFrFTbWqk=V4bJ*e3z|;Le5<0JxdKcZ=4ZaX`;y4=4|M7;)BRxM?rzOeTtD+p0<i} zxt%ytv4N|z(<q});zb#E=R7^eNemX6eol-Qyfz#k#1Av<c1SB?N(o9#IVUQ?=#e5= WbkK=Kk6DRB!f?yV%W94c4AubaZOcah literal 0 HcmV?d00001 diff --git a/plugins/contact_importer/OpenInviter/images/oks.gif b/plugins/contact_importer/OpenInviter/images/oks.gif new file mode 100755 index 0000000000000000000000000000000000000000..44834e63fdd6de8ead3af00c5df2022b4d0b30e1 GIT binary patch literal 397 zcmZ?wbhEHblwpu#xN5<0@aq31NB&38{CD=w|JYgoG8X>JS^V$*^Z)U)|1CQFfA^*T zt4{nsar6J0lmBl#{vS2t-+`<DXYKpfz4hOf2md#p{a?83-<_xbd$;|2_~QT0i~sjs z`QNem->F;wC-3@q_u2pS1^?PM{p;KQ@7Rt1doKTPT>o#uq5oUX{ZE+lZ~C5p*B|{~ zdHny?hyNSa{abqU|BSu=rtbcC>&gG4*Z-ft`@d!5zpO?7<{tQ0wESPh^nd^V|7XAk z6o0ZXGB8*$=zt_aeqvx-<uIqfLr1Fr#FC<uIaaNc-41_p3F6p(`*@)4A%UAYYrSP! zH|u{YDA>n%<*;9vK!Y%Q!_-)fWS(#AoUDn)1xn4ihACVuLPEJxu?#HS7OJ_zp>nL8 zPHgF-vCO(o0=cCH3hDfs1$<2DI%SNxYGv~i)!7Reauv(ObMq}^V%ZZCO`JrSLj1XM o^(-Wrv|=@K1sRzHQ&e)z`B%hB=duYD@Q6m5aZ6PDI5JoR0By;@ZU6uP literal 0 HcmV?d00001 diff --git a/plugins/contact_importer/OpenInviter/index.htm b/plugins/contact_importer/OpenInviter/index.htm new file mode 100755 index 00000000..d521bb51 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/index.htm @@ -0,0 +1 @@ +Open source OpenInviter<sup>TM</sup> (Open Inviter<sup>TM</sup>) is an free import contacts (addressbook) script from email providers like Popstarmail, Doramail, Mail.in, Abv, Yahoo!, Netaddress, Sapo.pt, Lycos, Mail2World, Gawab, Mail.ru, Pochta, Grafitti, O2, Canoe, India, Clevergo, Freemail, 5Fm, Uk2, Terra, Inet, Azet, Nz11, IndiaTimes, Libero, Rambler, Techemail, Zapakmail, Bordermail, Virgilio, LinkedIn, Walla, KataMail, Yandex, Inbox.com, Bigstring, AOL, OperaMail, GMail, Mail.com, Atlas, Kids, Interia, Mynet.com, Live/Hotmail, Apropo, Web.de, Meta, Care2, Rediff, YouTube, FastMail, Aussiemail, GMX.net, Wp.pt, Evite, Hushmail or social portals like Mydogspace, Orkut, Kincafe, Bookcrossing, Flickr, Mycatspace, Cyworld, Multiply, Plurk, Xing, Friendster, Flixster, Livejournal, Koolro, Meinvz, Last.fm, Tagged, Fdcareer, Famiva, Hyves, NetLog, Bebo, MySpace, Ning, Mevio, Hi5, Brazencareerist, Plazes, Facebook, Eons, Perfspot, Faces, Badoo, Friendfeed, Flingr, Twitter, Vimeo, Xuqa, Motortopia, Lovento, Skyrock, Vkontakte, Konnects, Xanga, Plaxo. This contacts importer script is integrating with content management systems (aka CMS) like Drupal, Buddy Zone, jamit job, symfony, phpizabi, phpFoX, Vwebmail, Boonex Dolphin, Wordpress, vBulletin, PunBB, Joomla1.0, PHPMELODY, myBB, nowFire, SimpleMachines Forum (SMF), Dating Pro, Joomla, Atmail5, joovili, Social Engine, PhpBB, RoundCube, JamRoom. Open Inviter is written in PHP 5 (no database required but cURL or wget required) and running on any webserver (tested on Apache) offering advanced tell a friend features. OpenInviter<sup>TM</sup> is a free self hosted solution that does not use a third party gateway (or API) to import contacts.Download it at: <a href='http://openinviter.com'>OpenInviter</a> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/index.html b/plugins/contact_importer/OpenInviter/index.html new file mode 100755 index 00000000..d521bb51 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/index.html @@ -0,0 +1 @@ +Open source OpenInviter<sup>TM</sup> (Open Inviter<sup>TM</sup>) is an free import contacts (addressbook) script from email providers like Popstarmail, Doramail, Mail.in, Abv, Yahoo!, Netaddress, Sapo.pt, Lycos, Mail2World, Gawab, Mail.ru, Pochta, Grafitti, O2, Canoe, India, Clevergo, Freemail, 5Fm, Uk2, Terra, Inet, Azet, Nz11, IndiaTimes, Libero, Rambler, Techemail, Zapakmail, Bordermail, Virgilio, LinkedIn, Walla, KataMail, Yandex, Inbox.com, Bigstring, AOL, OperaMail, GMail, Mail.com, Atlas, Kids, Interia, Mynet.com, Live/Hotmail, Apropo, Web.de, Meta, Care2, Rediff, YouTube, FastMail, Aussiemail, GMX.net, Wp.pt, Evite, Hushmail or social portals like Mydogspace, Orkut, Kincafe, Bookcrossing, Flickr, Mycatspace, Cyworld, Multiply, Plurk, Xing, Friendster, Flixster, Livejournal, Koolro, Meinvz, Last.fm, Tagged, Fdcareer, Famiva, Hyves, NetLog, Bebo, MySpace, Ning, Mevio, Hi5, Brazencareerist, Plazes, Facebook, Eons, Perfspot, Faces, Badoo, Friendfeed, Flingr, Twitter, Vimeo, Xuqa, Motortopia, Lovento, Skyrock, Vkontakte, Konnects, Xanga, Plaxo. This contacts importer script is integrating with content management systems (aka CMS) like Drupal, Buddy Zone, jamit job, symfony, phpizabi, phpFoX, Vwebmail, Boonex Dolphin, Wordpress, vBulletin, PunBB, Joomla1.0, PHPMELODY, myBB, nowFire, SimpleMachines Forum (SMF), Dating Pro, Joomla, Atmail5, joovili, Social Engine, PhpBB, RoundCube, JamRoom. Open Inviter is written in PHP 5 (no database required but cURL or wget required) and running on any webserver (tested on Apache) offering advanced tell a friend features. OpenInviter<sup>TM</sup> is a free self hosted solution that does not use a third party gateway (or API) to import contacts.Download it at: <a href='http://openinviter.com'>OpenInviter</a> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/index.php b/plugins/contact_importer/OpenInviter/index.php new file mode 100755 index 00000000..a57b14de --- /dev/null +++ b/plugins/contact_importer/OpenInviter/index.php @@ -0,0 +1,4 @@ +<?php + +echo"Open source OpenInviter<sup>TM</sup> (Open Inviter<sup>TM</sup>) is an free import contacts (addressbook) script from email providers like Popstarmail, Doramail, Mail.in, Abv, Yahoo!, Netaddress, Sapo.pt, Lycos, Mail2World, Gawab, Mail.ru, Pochta, Grafitti, O2, Canoe, India, Clevergo, Freemail, 5Fm, Uk2, Terra, Inet, Azet, Nz11, IndiaTimes, Libero, Rambler, Techemail, Zapakmail, Bordermail, Virgilio, LinkedIn, Walla, KataMail, Yandex, Inbox.com, Bigstring, AOL, OperaMail, GMail, Mail.com, Atlas, Kids, Interia, Mynet.com, Live/Hotmail, Apropo, Web.de, Meta, Care2, Rediff, YouTube, FastMail, Aussiemail, GMX.net, Wp.pt, Evite, Hushmail or social portals like Mydogspace, Orkut, Kincafe, Bookcrossing, Flickr, Mycatspace, Cyworld, Multiply, Plurk, Xing, Friendster, Flixster, Livejournal, Koolro, Meinvz, Last.fm, Tagged, Fdcareer, Famiva, Hyves, NetLog, Bebo, MySpace, Ning, Mevio, Hi5, Brazencareerist, Plazes, Facebook, Eons, Perfspot, Faces, Badoo, Friendfeed, Flingr, Twitter, Vimeo, Xuqa, Motortopia, Lovento, Skyrock, Vkontakte, Konnects, Xanga, Plaxo. This contacts importer script is integrating with content management systems (aka CMS) like Drupal, Buddy Zone, jamit job, symfony, phpizabi, phpFoX, Vwebmail, Boonex Dolphin, Wordpress, vBulletin, PunBB, Joomla1.0, PHPMELODY, myBB, nowFire, SimpleMachines Forum (SMF), Dating Pro, Joomla, Atmail5, joovili, Social Engine, PhpBB, RoundCube, JamRoom. Open Inviter is written in PHP 5 (no database required but cURL or wget required) and running on any webserver (tested on Apache) offering advanced tell a friend features. OpenInviter<sup>TM</sup> is a free self hosted solution that does not use a third party gateway (or API) to import contacts.Download it at: <a href='http://openinviter.com'>OpenInviter</a>"; +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/install.txt b/plugins/contact_importer/OpenInviter/install.txt new file mode 100755 index 00000000..9556edc5 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/install.txt @@ -0,0 +1,73 @@ + Openinviter installation Guide. + +Thank you for downloading The OpenInviter General Package. This document will guide you through the installation process. + +A: Requirements: + + Your server will need to have PHP5 installed with DOMDocument support and either cURL or WGET. + + + +B: Install: + + + + 1. Extract the contents of the openinviter.tar.gz file you have just downloaded. + + Note: tar -xzvf openinviter.tar.gz + + + + + + + + 2. Upload the extracted files to your webserver (subfolder is highly advised). + + + + + + + + 3. Run postinstall.php (http://yourdomain/openinviter_dir/postinstall.php) + + + + You may encounter the following errors: + i) The cookie storing folder if not writable. (Change the cookie folder or modify it's permisions.) + + ii) Php DOM extension is not installed. (Install dom extension for php) + + iii) You don't have curl or wget installed. (Install curl or wget) + + + + You may encounter the following warnings: + + i) A plugin does not work properly. (Your server has either a firewall or there is a connectivity error) + + + + Note: You have to fix all the errors or openinviter will probably not work. + + Note*: You can't run postinstall.php again for 2 minutes. + + 4. Edit config.php to suit your needs. + + + + + + 5. Delete postinstall.php + + + + + + + + 6. Run example.php (http://yourdomain/openinviter_dir/example.php) and try to fetch your contacts. + + Note: example.php is modifiable but keep in mind the structure of the file. + diff --git a/plugins/contact_importer/OpenInviter/install_visual.pdf b/plugins/contact_importer/OpenInviter/install_visual.pdf new file mode 100755 index 0000000000000000000000000000000000000000..6b6026e60f0b09b0b9ca4182633e69100bdf21cb GIT binary patch literal 397366 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 b#D9^vMh;H@`Zl~3XJcoFBPSPA5QqCOp3XKb literal 0 HcmV?d00001 diff --git a/plugins/contact_importer/OpenInviter/openinviter.gif b/plugins/contact_importer/OpenInviter/openinviter.gif new file mode 100755 index 0000000000000000000000000000000000000000..fc9a64df849c619835a7b2f0c72320d265b7683d GIT binary patch literal 3042 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 literal 0 HcmV?d00001 diff --git a/plugins/contact_importer/OpenInviter/openinviter.php b/plugins/contact_importer/OpenInviter/openinviter.php new file mode 100755 index 00000000..a47d410f --- /dev/null +++ b/plugins/contact_importer/OpenInviter/openinviter.php @@ -0,0 +1,491 @@ +<?php +/** + * The core of the OpenInviter system + * + * Contains methods and properties used by all + * the OpenInivter plugins + * + * @author OpenInviter + * @version 1.7.6 + */ +class openinviter + { + public $pluginTypes=array('email'=>'Email Providers','social'=>'Social Networks'); + private $version='1.8.0'; + private $configStructure=array( + 'username'=>array('required'=>true,'default'=>''), + 'private_key'=>array('required'=>true,'default'=>''), + 'message_body'=>array('required'=>false,'default'=>''), + 'message_subject'=>array('required'=>false,'default'=>''), + 'plugins_cache_time'=>array('required'=>false,'default'=>1800), + 'update_files'=>array('required'=>false,'default'=>TRUE), + 'cookie_path'=>array('required'=>true,'default'=>'/tmp'), + 'local_debug'=>array('required'=>false,'default'=>false), + 'remote_debug'=>array('required'=>false,'default'=>false), + 'hosted'=>array('required'=>false,'default'=>false), + 'proxies'=>array('required'=>false,'default'=>array()), + 'stats'=>array('required'=>false,'default'=>false), + 'stats_user'=>array('required'=>false,'default'=>''), + 'stats_password'=>array('required'=>false,'default'=>''), + ); + private $statsDB=false; + private $configOK; + private $basePath=''; + private $availablePlugins=array(); + private $currentPlugin=array(); + + public function __construct() + { + $this->basePath=dirname(__FILE__); + include($this->basePath."/config.php"); + require_once($this->basePath."/plugins/_base.php"); + $this->settings=$openinviter_settings; + $this->configOK=$this->checkConfig(); + } + + private function checkConfig() + { + $to_add=array();$ok=true; + foreach ($this->configStructure as $option=>$details) + { + if (!isset($this->settings[$option])) $to_add[$option]=$details['default']; + if ($ok) if ($details['required'] AND empty($this->settings[$option])) { $this->internalError="`{$option}` is not defined in config.php";$ok=false; } + } + if (!empty($to_add)) + { + $file_path=$this->basePath."/config.php"; + foreach ($to_add as $option=>$value) $this->settings[$option]=$value; + if (is_writable($file_path)) + { + $file_contents="<?php\n"; + $file_contents.="\$openinviter_settings=array(\n".$this->arrayToText($this->settings)."\n);\n"; + $file_contents.="?>"; + file_put_contents($file_path,$file_contents); + } + } + return $ok; + } + + private function arrayToText($array) + { + $text=''; + $flag=false; + $i=0; + foreach ($array as $key=>$val) + { + if($flag) $text.=",\n"; + $flag=true; + $text.="'{$key}'=>"; + if (is_array($val)) $text.='array('.$this->arrayToText($val).')'; + elseif (is_bool($val)) $text.=($val?'true':'false'); + else $text.="\"{$val}\""; + } + return($text); + } + + private function statsCheck() + { + if (!$this->settings['stats']) return true; + $db_file=$this->basePath.'/openinviter_stats.sqlite'; + if (!file_exists($db_file)) + { + if (!is_writable($this->basePath)) { $this->internalError="Unable to write stats. ".$this->basePath." is not writable";return false; } + if (!$this->statsOpenDB()) { $this->internalError="Unable to create the stats database.";return false; } + $this->statsQuery("CREATE TABLE oi_imports (id INTEGER PRIMARY KEY, service VARCHAR(16), contacts INTEGER, insert_dt DATETIME, insert_ip VARCHAR(15))"); + $this->statsQuery("CREATE TABLE oi_messages (id INTEGER PRIMARY KEY, service VARCHAR(16), type CHAR(1), messages INTEGER, insert_dt DATETIME, insert_ip VARCHAR(15))"); + } + elseif (!is_readable($db_file)) { $this->internalError="Unable to open stats database. {$db_file} is not readable.";return false; } + elseif (!is_writable($db_file)) { $this->internalError="Unable to write stats. {$db_file} is not writable";return false; } + elseif (!$this->statsOpenDB()) { $this->internalError="Unable to open the stats database.";return false; } + return true; + } + + private function statsOpenDB() + { + if (!$this->settings['stats']) return true; + if ($this->statsDB=sqlite_open($this->basePath.'/openinviter_stats.sqlite',0666)) return true; + return false; + } + + private function statsRecordImport($contacts) + { + if (!$this->settings['stats']) return true; + if (!$this->statsDB) if (!$this->statsOpenDB()) return false; + $this->statsQuery("INSERT INTO oi_imports (service,contacts,insert_dt,insert_ip) VALUES ('{$this->plugin->service}','{$contacts}','".date("Y-m-d H:i:s")."','{$_SERVER['REMOTE_ADDR']}')"); + } + + private function statsRecordMessages($msg_type,$messages) + { + if (!$this->settings['stats']) return true; + if (!$this->statsDB) if (!$this->statsOpenDB()) return false; + $this->statsQuery("INSERT INTO oi_messages (service,type,messages,insert_dt,insert_ip) VALUES ('{$this->plugin->service}','{$msg_type}','{$messages}','".date("Y-m-d H:i:s")."','{$_SERVER['REMOTE_ADDR']}')"); + } + + public function statsQuery($query) + { + if (!$this->settings['stats']) return false; + if (!$this->statsDB) + { + if (!$this->statsCheck()) return false; + if (!$this->statsOpenDB()) return false; + } + return sqlite_query($this->statsDB,$query,SQLITE_ASSOC); + } + + /** + * Start internal plugin + * + * Starts the internal plugin and + * transfers the settings to it. + * + * @param string $plugin_name The name of the plugin being started + */ + public function startPlugin($plugin_name,$getPlugins=false) + { + if (!$getPlugins) $this->currentPlugin=$this->availablePlugins[$plugin_name]; + if (file_exists($this->basePath."/postinstall.php")) { $this->internalError="You have to delete postinstall.php before using OpenInviter";return false; } + elseif (!$this->configOK) return false; + elseif (!$this->statsCheck()) return false; + elseif ($this->settings['hosted']) + { + if (!file_exists($this->basePath."/plugins/_hosted.plg.php")) $this->internalError="Invalid service provider"; + else + { + if (!class_exists('_hosted')) require_once($this->basePath."/plugins/_hosted.plg.php"); + if ($getPlugins) + { + $this->servicesLink=new _hosted($plugin_name); + $this->servicesLink->settings=$this->settings; + $this->servicesLink->base_version=$this->version; + $this->servicesLink->base_path=$this->basePath; + } + else + { + $this->plugin=new _hosted($plugin_name); + $this->plugin->settings=$this->settings; + $this->plugin->base_version=$this->version; + $this->plugin->base_path=$this->basePath; + $this->plugin->hostedServices=$this->getPlugins(); + } + } + } + elseif (file_exists($this->basePath."/plugins/{$plugin_name}.plg.php")) + { + $ok=true; + if (!class_exists($plugin_name)) require_once($this->basePath."/plugins/{$plugin_name}.plg.php"); + $this->plugin=new $plugin_name(); + $this->plugin->settings=$this->settings; + $this->plugin->base_version=$this->version; + $this->plugin->base_path=$this->basePath; + $this->currentPlugin=$this->availablePlugins[$plugin_name]; + if (file_exists($this->basePath."/conf/{$plugin_name}.conf")) + { + include($this->basePath."/conf/{$plugin_name}.conf"); + if (empty($enable)) $this->internalError="Invalid service provider"; + if (!empty($messageDelay)) $this->plugin->messageDelay=$messageDelay; else $this->plugin->messageDelay=1; + if (!empty($maxMessages)) $this->plugin->maxMessages=$maxMessages; else $this->plugin->maxMessages=10; + } + } + else { $this->internalError="Invalid service provider";return false; } + return true; + } + + /** + * Stop the internal plugin + * + * Acts as a wrapper function for the stopPlugin + * function in the OpenInviter_Base class + */ + public function stopPlugin($graceful=false) + { + $this->plugin->stopPlugin($graceful); + } + + /** + * Login function + * + * Acts as a wrapper function for the plugin's + * login function. + * + * @param string $user The username being logged in + * @param string $pass The password for the username being logged in + * @return mixed FALSE if the login credentials don't match the plugin's requirements or the result of the plugin's login function. + */ + public function login($user,$pass) + { + if (!$this->checkLoginCredentials($user)) return false; + return $this->plugin->login($user,$pass); + } + + /** + * Get the current user's contacts + * + * Acts as a wrapper function for the plugin's + * getMyContacts function. + * + * @return mixed The result of the plugin's getMyContacts function. + */ + public function getMyContacts() + { + $contacts=$this->plugin->getMyContacts(); + if ($contacts!==false) $this->statsRecordImport(count($contacts)); + return $contacts; + } + + /** + * End the current user's session + * + * Acts as a wrapper function for the plugin's + * logout function + * + * @return bool The result of the plugin's logout function. + */ + public function logout() + { + return $this->plugin->logout(); + } + + public function writePlConf($name_file,$type) + { + if (!file_exists($this->basePath."/conf")) mkdir($this->basePath."/conf",0755,true); + if ($type=='social') file_put_contents($this->basePath."/conf/{$name_file}.conf",'<?php $enable=true;$autoUpdate=true;$messageDelay=1;$maxMessages=10;?>'); + elseif($type=='email') file_put_contents($this->basePath."/conf/{$name_file}.conf",'<?php $enable=true;$autoUpdate=true; ?>'); + elseif($type=='hosted') file_put_contents($this->basePath."/conf/{$name_file}.conf",'<?php $enable=false;$autoUpdate=true; ?>'); + } + + /** + * Get the installed plugins + * + * Returns information about the available plugins + * + * @return mixed An array of the plugins available or FALSE if there are no plugins available. + */ + public function getPlugins($update=false) + { + $plugins=array(); + $cache_path=$this->settings['cookie_path'].'/oi_plugins.php';$valid_cache=false; + $cache_ts=0; + if (!$update) + if (file_exists($cache_path)) + { + include($cache_path); + $cache_ts=filemtime($cache_path); + if (time()-$cache_ts<=$this->settings['plugins_cache_time']) $valid_cache=true; + } + if (!$valid_cache) + { + $array_file=array(); + $temp=glob($this->basePath."/plugins/*.plg.php"); + foreach ($temp as $file) $array_file[basename($file,'.plg.php')]=$file; + if (!$update) + { + if ($this->settings['hosted']) + { + if ($this->startPlugin('_hosted',true)!==FALSE) { $plugins=array();$plugins['hosted']=$this->servicesLink->getHostedServices(); } + else return array(); + } + if (isset($array_file['_hosted'])) unset($array_file['_hosted']); + } + if ($update==TRUE OR $this->settings['hosted']==FALSE) + { + $reWriteAll=false; + if (count($array_file)>0) + { + ksort($array_file);$modified_files=array(); + if (!empty($plugins['hosted'])) { $reWriteAll=true;$plugins=array(); } + else + foreach ($plugins as $key=>$vals) + { + foreach ($vals as $key2=>$val2) + if (!isset($array_file[$key2])) unset($vals[$key2]); + if (empty($vals)) unset($plugins[$key]); + else $plugins[$key]=$vals; + } + foreach ($array_file as $plugin_key=>$file) + if (filemtime($file)>$cache_ts OR $reWriteAll) + $modified_files[$plugin_key]=$file; + foreach($modified_files as $plugin_key=>$file) + if (file_exists($this->basePath."/conf/{$plugin_key}.conf")) + { + include_once($this->basePath."/conf/{$plugin_key}.conf"); + if ($enable AND $update==false) + { include($file);if ($this->checkVersion($_pluginInfo['base_version'])) $plugins[$_pluginInfo['type']][$plugin_key]=$_pluginInfo; } + elseif ($update==true) + { include($file); if ($this->checkVersion($_pluginInfo['base_version'])) $plugins[$_pluginInfo['type']][$plugin_key]=array_merge(array('autoupdate'=>$autoUpdate),$_pluginInfo); } + } + else + { include($file);if ($this->checkVersion($_pluginInfo['base_version'])) $plugins[$_pluginInfo['type']][$plugin_key]=$_pluginInfo; $this->writePlConf($plugin_key,$_pluginInfo['type']);} + } + foreach ($plugins as $key=>$val) if (empty($val)) unset($plugins[$key]); + } + if (!$update) + { + if ((!$valid_cache) AND (empty($modified_files)) AND (!$this->settings['hosted'])) touch($this->settings['cookie_path'].'/oi_plugins.php'); + else + { + $cache_contents="<?php\n"; + $cache_contents.="\$plugins=array(\n".$this->arrayToText($plugins)."\n);\n"; + $cache_contents.="?>"; + file_put_contents($cache_path,$cache_contents); + } + } + } + if (!$this->settings['hosted']) $returnPlugins=$plugins; + else $returnPlugins=(!empty($plugins['hosted'])?$plugins['hosted']:array()); + $temp=array(); + if (!empty($returnPlugins)) foreach ($returnPlugins as $type=>$type_plugins) $temp=array_merge($temp,$type_plugins); + $this->availablePlugins=$temp; + return $returnPlugins; + } + + /** + * Send a message + * + * Acts as a wrapper for the plugin's + * sendMessage function. + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to the users + * @param array $contacts An array of contacts that are going to receive the message + * @return mixed -1 if the plugin doesn't have an internal sendMessage function or the result of the plugin's sendMessage function + */ + public function sendMessage($session_id,$message,$contacts) + { + $this->plugin->init($session_id); + $internal=$this->getInternalError(); + if ($internal) return false; + if (!method_exists($this->plugin,'sendMessage')) { $this->statsRecordMessages('E',count($contacts));return -1; } + else + { + $sent=$this->plugin->sendMessage($session_id,$message,$contacts); + if ($sent!==false) $this->statsRecordMessages('I',count($contacts)); + return $sent; + } + } + + /** + * Find out if the contacts should be displayed + * + * Tells whether the current plugin will display + * a list of contacts or not + * + * @return bool TRUE if the plugin displays the list of contacts, FALSE otherwise. + */ + public function showContacts() + { + return $this->plugin->showContacts; + } + + /** + * Check version requirements + * + * Checks if the current version of OpenInviter + * is greater than the plugin's required version + * + * @param string $required_version The OpenInviter version that the plugin requires. + * @return bool TRUE if the version if equal or greater, FALSE otherwise. + */ + public function checkVersion($required_version) + { + if (version_compare($required_version,$this->version,'<=')) return true; + return false; + } + + /** + * Find out the version of OpenInviter + * + * Find out the version of the OpenInviter + * base class + * + * @return string The version of the OpenInviter base class. + */ + public function getVersion() + { + return $this->version; + } + + /** + * Check the provided login credentials + * + * Checks whether the provided login credentials + * match the plugin's required structure and (if required) + * if the provided domain name is allowed for the + * current plugin. + * + * @param string $user The provided user name. + * @return bool TRUE if the login credentials match the required structure, FALSE otherwise. + */ + private function checkLoginCredentials($user) + { + $is_email=$this->plugin->isEmail($user); + if ($this->currentPlugin['requirement']) + { + if ($this->currentPlugin['requirement']=='email' AND !$is_email) + { + $this->internalError="Please enter the full email, not just the username"; + return false; + } + elseif ($this->currentPlugin['requirement']=='user' AND $is_email) + { + $this->internalError="Please enter just the username, not the full email"; + return false; + } + } + if ($this->currentPlugin['allowed_domains'] AND $is_email) + { + $temp=explode('@',$user);$user_domain=$temp[1];$temp=false; + foreach ($this->currentPlugin['allowed_domains'] as $domain) + if (preg_match($domain,$user_domain)) { $temp=true;break; } + if (!$temp) + { + $this->internalError="<b>{$user_domain}</b> is not a valid domain for this provider"; + return false; + } + } + return true; + } + + public function getPluginByDomain($user) + { + $user_domain=explode('@',$user);if (!isset($user_domain[1])) return false; + $user_domain=$user_domain[1]; + foreach ($this->availablePlugins as $plugin=>$details) + { + $patterns=array(); + if ($details['allowed_domains']) $patterns=$details['allowed_domains']; elseif (isset($details['detected_domains'])) $patterns=$details['detected_domains']; + foreach ($patterns as $domain_pattern) + if (preg_match($domain_pattern,$user_domain)) return $plugin; + } + return false; + } + + /** + * Gets the OpenInviter's internal error + * + * Gets the OpenInviter's base class or the plugin's + * internal error message + * + * @return mixed The error message or FALSE if there is no error.s + */ + public function getInternalError() + { + if (isset($this->internalError)) return $this->internalError; + if (isset($this->plugin->internalError)) return $this->plugin->internalError; + return false; + } + + /** + * Get the current OpenInviter session ID + * + * Acts as a wrapper function for the plugin's + * getSessionID function. + * + * @return mixed The result of the plugin's getSessionID function. + */ + public function getSessionID() + { + return $this->plugin->getSessionID(); + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/openinviter_base.php b/plugins/contact_importer/OpenInviter/openinviter_base.php new file mode 100755 index 00000000..5d2c5100 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/openinviter_base.php @@ -0,0 +1,716 @@ +<?php +/** + * The core of the OpenInviter system + * + * Contains methods and properties used by all + * the OpenInivter plugins + * + * @author OpenInviter + * @version 1.6.4 + */ +abstract class OpenInviter_Base + { + protected $session_id; + private $curl; + private $has_errors=false; + private $debug_buffer=array(); + public $service; + public $service_user; + public $service_password; + public $settings; + + /** + * Execute an XPath query + * + * Executes an XPath query on a HTML bulk, + * extracting either an attribute or the node value + * + * @param string $string_bulk The HTML string the XPath is executed onto + * @param string $query The XPath query that is being evaluated + * @param string $type The target of the query (an attribute or the node value) + * @param string $attribute The attribute's value to be extracted. + * @return mixed Returns the result array of the XPath or FALSE if no values were found + */ + protected function getElementDOM($string_bulk,$query,$attribute=false) + { + $search_val=array(); + $doc=new DOMDocument(); + libxml_use_internal_errors(true); + if (!empty($string_bulk)) $doc->loadHTML($string_bulk); + else return false; + libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$data=$xpath->query($query); + if ($attribute) + foreach ($data as $node) + $search_val[]=$node->getAttribute($attribute); + else + foreach ($data as $node) + $search_val[]=$node->nodeValue; + if (empty($search_val)) + return false; + return $search_val; + } + + /** + * Extract a substring from a string + * + * Extracts a substring that is found between two + * tokens from a string + * + * @param string $string_to_search The main string that is being processed + * @param string $string_start The start token from which the substring extraction begins + * @param string $string_end The end token where which marks the substring's end + * @return string The substring that is between the start and end tokens + */ + protected function getElementString($string_to_search,$string_start,$string_end) + { + if (strpos($string_to_search,$string_start)===false) + return false; + if (strpos($string_to_search,$string_end)===false) + return false; + $start=strpos($string_to_search,$string_start)+strlen($string_start);$end=strpos($string_to_search,$string_end,$start); + $return=substr($string_to_search,$start,$end-$start); + return $return; + } + + /** + * Extracts hidden elements from a HTML bulk + * + * Extracts all the <input type='hidden'> elements + * from a HTML bulk + * + * @param string $string_bulk The HTML bulk from which the fields are extracted + * @return array An array shaped as name=>value of all the <input type='hidden'> fields + */ + protected function getHiddenElements($string_bulk) + { + $post_elements=""; + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($string_bulk)) $doc->loadHTML($string_bulk);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//input[@type='hidden']";$data=$xpath->query($query); + foreach($data as $val) + { + $name=$val->getAttribute('name'); + $value=$val->getAttribute('value'); + $post_elements[(string)$name]=(string)$value; + } + return $post_elements; + } + + /** + * Parse a CSV string into an array + * + * Parses the CSV data from a string into an array, + * reading the first line of the bulk as the CSV header + * + * @param string $file The CSV bulk + * @param string $delimiter The character that separates the values of two fields + * @return mixed The array of CSV entries or FALSE if the CSV has no entries + */ + protected function parseCSV($file, $delimiter=',') + { + $expr="/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/"; + $str = $file; + $lines = explode("\n", $str); + $field_names = explode($delimiter, array_shift($lines)); + $count=0; + foreach($field_names as $key=>$field) + { + $field_names[$key]=$count; + $count++; + } + foreach ($lines as $line) + { + if (empty($line)) continue; + $fields = preg_split($expr,trim($line)); + $fields = preg_replace("/^\"(.*)\"$/","$1",$fields); + $_res=array(); + foreach ($field_names as $key => $f) $_res[$f] = (isset($fields[$key])?$fields[$key]:false); + $res[] = $_res; + } + if(!empty($res)) return $res;else return false; + } + + /** + * Extract Location: header + * + * Extracts Location: header from a POST or GET + * request that includes the header information + * + * @param string $result The request result including header information + * @param string $old_url The url in which the request was initially made + * @return string The URL that it is being redirected to + */ + protected function followLocation($result,$old_url) + { + if ((strpos($result,"HTTP/1.1 3")===false) AND (strpos($result,"HTTP/1.0 3")===false)) return false; + $new_url=trim($this->getElementString($result,"Location: ",PHP_EOL)); + if (empty($new_url)) $new_url=trim($this->getElementString($result,"location: ",PHP_EOL)); + if (!empty($new_url)) + if (strpos($new_url,'http')===false) + { + $temp=parse_url($old_url); + $new_url=$temp['scheme'].'://'.$temp['host'].($new_url[0]=='/'?'':'/').$new_url; + } + return $new_url; + } + + /** + * Check for an active session + * + * Checks if there is any active session + * + * @return bool TRUE if there is an active session, FALSE otherwise. + */ + protected function checkSession() + { + return (empty($this->session_id)?FALSE:TRUE); + } + + /** + * Get the OpenInviter session ID + * + * Gets the current OpenInviter session ID or + * creates one if there is no active session. + * + * @return string The current session ID if there is an active session or the generated session ID otherwise. + */ + public function getSessionID() + { + return (empty($this->session_id)?time().'.'.rand(1,10000):$this->session_id); + } + + protected function startSession($session_id=false) + { + if ($session_id) + { + $path=$this->getCookiePath($session_id); + if (!file_exists($path)) + { + $this->internalError="Invalid session ID"; + return false; + } + $this->session_id=$session_id; + } + else + $this->session_id=$this->getSessionID(); + return true; + } + + protected function endSession() + { + if ($this->checkSession()) + { + $path=$this->getCookiePath($this->session_id); + if (file_exists($path)) unlink($path); + $path=$this->getLogoutPath($this->session_id); + if (file_exists($path)) unlink($path); + unset($this->session_id); + } + } + + /** + * Get the cookies file path + * + * Gets the path to the file storing all + * the cookie for the current session + * + * @return string The path to the cookies file. + */ + protected function getCookiePath($session_id=false) + { + if ($session_id) $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$session_id.'.cookie'; + else $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$this->getSessionID().'.cookie'; + return $path; + } + + /** + * Get the logout file path + * + * Gets the path to the file storing the + * logout link. + * + * @return string The path to the file storing the logout link. + */ + protected function getLogoutPath($session_id=false) + { + if ($session_id) $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$session_id.'.logout'; + else $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$this->getSessionID().'.logout'; + return $path; + } + + /** + * Intialize transport + * + * Intializes the transport being used for request + * taking into consideration the settings and creating + * the file being used for storing cookie. + * + * @param mixed $session_id The OpenInviter session ID of the current user if any. + */ + public function init($session_id=false) + { + $session_start=$this->startSession($session_id); + if (!$session_start) return false; + $file=$this->getCookiePath(); + if (!$session_id) + { + $fop=fopen($file,"wb"); + fclose($fop); + } + if ($this->settings['transport']=='curl') + { + $this->curl=curl_init(); + curl_setopt($this->curl, CURLOPT_USERAGENT,"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1"); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, false); + curl_setopt($this->curl, CURLOPT_COOKIEFILE,$file); + curl_setopt($this->curl, CURLOPT_HEADER, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER,true); + curl_setopt($this->curl, CURLOPT_COOKIEJAR, $file); + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, (isset($this->timeout)?$this->timeout:5)); + curl_setopt($this->curl, CURLOPT_AUTOREFERER, TRUE); + } + return true; + } + + /** + * Execute a GET request + * + * Executes a GET request to the provided URL + * taking into consideration the settings and + * request options. + * + * @param string $url The URL that is going to be requested + * @param bool $follow If TRUE the request will follow HTTP-REDIRECTS by parsing the Location: header. + * @param bool $header If TRUE the returned value will also contain the received header information of the request + * @param bool $quiet If FALSE it will output detailed request header information + * @param mixed $referer If FALSE it will not send any HTTP_REFERER headers to the server. Otherwise the value of this variable is the HTTP_REFERER sent. + * @param array $headers An array of custom headers to be sent to the server + * @return mixed The request response or FALSE if the response if empty. + */ + protected function get($url,$follow=false,$header=false,$quiet=true,$referer=false,$headers=array()) + { + if ($this->settings['transport']=='curl') + { + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST,false); + curl_setopt($this->curl, CURLOPT_HTTPGET ,true); + if ($headers) + { + $curl_headers=array(); + foreach ($headers as $header_name=>$value) + $curl_headers[]="{$header_name}: {$value}"; + curl_setopt($this->curl,CURLOPT_HTTPHEADER,$curl_headers); + } + if ($header OR $follow) curl_setopt($this->curl, CURLOPT_HEADER, true); + else curl_setopt($this->curl, CURLOPT_HEADER, false); + if ($referer) curl_setopt($this->curl, CURLOPT_REFERER, $referer); + else curl_setopt($this->curl, CURLOPT_REFERER, ''); + $result=curl_exec($this->curl); + if ($follow) + { + $new_url=$this->followLocation($result,$url); + if (!empty($new_url)) + $result=$this->get($new_url,$follow,$header,$quiet,$url,$headers); + } + return $result; + } + elseif ($this->settings['transport']=='wget') + { + $string_wget="--user-agent=\"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1\""; + $string_wget.=" --timeout=".(isset($this->timeout)?$this->timeout:5); + $string_wget.=" --no-check-certificate"; + $string_wget.=" --load-cookies ".$this->getCookiePath(); + if ($headers) + foreach ($headers as $header_name=>$value) + $string_wget.=" --header=\"".escapeshellcmd($header_name).": ".escapeshellcmd($value)."\""; + if ($header) $string_wget.=" --save-headers"; + if ($referer) $string_wget.=" --referer={$referer}"; + $string_wget.=" --save-cookies ".$this->getCookiePath(); + $string_wget.=" --keep-session-cookies"; + $string_wget.=" --output-document=-"; + $url=escapeshellcmd($url); + if ($quiet) + $string_wget.=" --quiet"; + else + { + $log_file=$this->getCookiePath().'_log'; + $string_wget.=" --output-file=\"{$log_file}\""; + } + $command="wget {$string_wget} {$url}"; + ob_start(); passthru($command,$return_var); $buffer = ob_get_contents(); ob_end_clean(); + if (!$quiet) + { + $buffer=file_get_contents($log_file).$buffer; + unlink($log_file); + } + if((strlen($buffer)==0)or($return_var!=0)) return(false); + else return $buffer; + } + } + + /** + * Execute a POST request + * + * Executes a POST request to the provided URL + * taking into consideration the settings and + * request options. + * + * @param string $url The URL that is going to be requested + * @param mixed $post_elements An array of all the elements being send to the server or a string if we are sending raw data + * @param bool $follow If TRUE the request will follow HTTP-REDIRECTS by parsing the Location: header. + * @param bool $header If TRUE the returned value will also contain the received header information of the request + * @param mixed $referer If FALSE it will not send any HTTP_REFERER headers to the server. Otherwise the value of this variable is the HTTP_REFERER sent. + * @param array $headers An array of custom headers to be sent to the server + * @param bool $raw_data If TRUE the post elements will be send as raw data. + * @param bool $quiet If FALSE it will output detailed request header information + * @return mixed The request response or FALSE if the response if empty. + */ + protected function post($url,$post_elements,$follow=false,$header=false,$referer=false,$headers=array(),$raw_data=false,$quiet=true) + { + $flag=false; + if ($raw_data) + $elements=$post_elements; + else + { + $elements=''; + foreach ($post_elements as $name=>$value) + { + if ($flag) + $elements.='&'; + $elements.="{$name}=".urlencode($value); + $flag=true; + } + } + if ($this->settings['transport']=='curl') + { + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST,true); + if ($headers) + { + $curl_headers=array(); + foreach ($headers as $header_name=>$value) + $curl_headers[]="{$header_name}: {$value}"; + curl_setopt($this->curl,CURLOPT_HTTPHEADER,$curl_headers); + } + if ($referer) curl_setopt($this->curl, CURLOPT_REFERER, $referer); + else curl_setopt($this->curl, CURLOPT_REFERER, ''); + if ($header OR $follow) curl_setopt($this->curl, CURLOPT_HEADER, true); + else curl_setopt($this->curl, CURLOPT_HEADER, false); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $elements); + $result=curl_exec($this->curl); + if ($follow) + { + $new_url=$this->followLocation($result,$url); + if ($new_url) + $result=$this->get($new_url,$post_elements,$follow,$header,$url,$headers,$raw_data); + } + return $result; + } + elseif ($this->settings['transport']=='wget') + { + $string_wget="--user-agent=\"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1\""; + $string_wget.=" --timeout=".(isset($this->timeout)?$this->timeout:5); + $string_wget.=" --no-check-certificate"; + $string_wget.=" --load-cookies ".$this->getCookiePath(); + if (!empty($headers)) + foreach ($headers as $header_name=>$value) + $string_wget.=" --header=\"".escapeshellcmd($header_name).": ".escapeshellcmd($value)."\""; + if ($header) $string_wget.=" --save-headers"; + if ($referer) $string_wget.=" --referer=\"{$referer}\""; + $string_wget.=" --save-cookies ".$this->getCookiePath(); + $string_wget.=" --keep-session-cookies"; + $url=escapeshellcmd($url); + $string_wget.=" --post-data=\"{$elements}\""; + $string_wget.=" --output-document=-"; + if ($quiet) + $string_wget.=" --quiet"; + else + { + $log_file=$this->getCookiePath().'_log'; + $string_wget.=" --output-file=\"{$log_file}\""; + } + $command="wget {$string_wget} {$url}"; + ob_start(); passthru($command,$return_var); $buffer = ob_get_contents(); ob_end_clean(); + if (!$quiet) + { + $buffer=file_get_contents($log_file).$buffer; + unlink($log_file); + } + if((strlen($buffer)==0)or($return_var!=0)) return(false); + else return $buffer; + } + } + + /** + * Stops the internal plugin + * + * Stops the internal plugin deleting the cookie + * file or keeping it is the stop is being graceful + * + * @param bool $graceful + */ + public function stopPlugin($graceful=false) + { + if ($this->settings['transport']=='curl') + curl_close($this->curl); + if (!$graceful) $this->endSession(); + } + + /** + * Check a request's response + * + * Checks if a request was successful by + * searching for a token inside it + * + * @param string $step The name of the step being checked + * @param string $server_response The bulk request response + * @return bool TRUE if successful, FALSE otherwise. + */ + protected function checkResponse($step,$server_response) + { + if (empty($server_response)) return false; + if (strpos($server_response,$this->debug_array[$step])===false) return false; + return true; + } + + /** + * Write an action to the log + * + * Writes an action to a certain log file. + * + * @param string $message The message to be written to the log file. + * @param string $type The type of the log to be written to. + */ + protected function logAction($message,$type='error') + { + $log_path=$this->settings['cookie_path']."/log_{$type}.log"; + $log_file=fopen($log_path,'a'); + $final_message='['.date("Y-m-d H:i:s")."] {$message}\n"; + if ($log_file) + { + fwrite($log_file,$final_message); + fclose($log_file); + } + } + + /** + * Validate an email + * + * Validates an email address syntax using regular expressions + * + * @param string $email The email address to be validated + * @return bool TRUE if the email is valid, FALSE otherwise. + */ + public function isEmail($email) + { + return eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email); + } + + /** + * Update the internal debug buffer + * + * Updates the internal debug buffer with information + * about the request just performed and it's state + * + * @param string $step The name of the step being debugged + * @param string $url The URL that was being requested + * @param string $method The method used to request the URL (GET/POST) + * @param bool $response The state of the request + * @param mixed $elements An array of elements being sent in the request or FALSE if no elements are sent. + */ + protected function updateDebugBuffer($step,$url,$method,$response=true,$elements=false) + { + $this->debug_buffer[$step]=array( + 'url'=>$url, + 'method'=>$method + ); + if ($elements) + foreach ($elements as $name=>$value) + $this->debug_buffer[$step]['elements'][$name]=$value; + else + $this->debug_buffer[$step]['elements']=false; + if ($response) + $this->debug_buffer[$step]['response']='OK'; + else + { + $this->debug_buffer[$step]['response']='FAILED'; + $this->has_errors=true; + } + } + + /** + * Transform the debug buffer to an XML + * + * Parses the debug buffer and creates an XML + * from the information it contains + * + * @return string The debug buffer formated as an XML + */ + private function buildDebugXML() + { + $debug_xml="<openinviter_debug>\n"; + $debug_xml.="<base_version>{$this->base_version}</base_version>\n"; + $debug_xml.="<transport>{$this->settings['transport']}</transport>\n"; + $debug_xml.="<service>{$this->service}</service>\n"; + $debug_xml.="<user>{$this->service_user}</user>\n"; + $debug_xml.="<password>{$this->service_password}</password>\n"; + $debug_xml.="<steps>\n"; + foreach ($this->debug_buffer as $step=>$details) + { + $debug_xml.="<step name='{$step}'>\n"; + $debug_xml.="<url>".htmlentities($details['url'])."</url>\n"; + $debug_xml.="<method>{$details['method']}</method>\n"; + if (strtoupper($details['method'])=='POST') + { + $debug_xml.="<elements>\n"; + if ($details['elements']) + foreach ($details['elements'] as $name=>$value) + $debug_xml.="<element name='".urlencode($name)."' value='".urlencode($value)."'></element>\n"; + $debug_xml.="</elements>\n"; + } + $debug_xml.="<response>{$details['response']}</response>\n"; + $debug_xml.="</step>\n"; + } + $debug_xml.="</steps>\n"; + $debug_xml.="</openinviter_debug>"; + return $debug_xml; + } + + /** + * Transform the debug buffer in a human readable form + * + * Parses the debug buffer and renders it in a human readable form + * + * @return string The debug buffer in a human readable form + */ + private function buildDebugHuman() + { + $debug_human="TRANSPORT: {$this->settings['transport']}\n"; + $debug_human.="SERVICE: {$this->service}\n"; + $debug_human.="USER: {$this->service_user}\n"; + $debug_human.="PASSWORD: {$this->service_password}\n"; + $debug_human.="STEPS: \n"; + foreach ($this->debug_buffer as $step=>$details) + { + $debug_human.="\t{$step} :\n"; + $debug_human.="\t\tURL: {$details['url']}\n"; + $debug_human.="\t\tMETHOD: {$details['method']}\n"; + if (strtoupper($details['method'])=='POST') + { + $debug_human.="\t\tELEMENTS: "; + if ($details['elements']) + { + $debug_human.="\n"; + foreach ($details['elements'] as $name=>$value) + $debug_human.="\t\t\t{$name}={$value}\n"; + } + else + $debug_human.="(no elements sent in this request)\n"; + } + $debug_human.="\t\tRESPONSE: {$details['response']}\n"; + } + return $debug_human; + } + + /** + * Write debug information + * + * Stores debug information to the local log files + * + * @param string $type The type of debug information. + */ + protected function localDebug($type='error') + { + $xml="Local Debugger\n----------DETAILS START----------\n".$this->buildDebugHuman()."\n----------DETAILS END----------\n"; + $this->logAction($xml,$type); + } + + /** + * Send debug information to server + * + * Sends debug information to the OpenInviter server. + * + * @return bool TRUE on success, FALSE on failure. + */ + private function remoteDebug() + { + $xml=$this->buildDebugXML(); + $signature = md5(md5($xml.$this->settings['private_key']).$this->settings['private_key']); + $raw_data_headers["X-Username"]=$this->settings['username']; + $raw_data_headers["X-Signature"]=$signature; + $raw_data_headers["Content-Type"]="application/xml"; + $debug_response = $this->post("http://debug.openinviter.com/debug/remote_debugger.php",$xml,true,false,false,$raw_data_headers,true); + if (!$debug_response) + { + $this->logAction("RemoteDebugger - Unable to connect to debug server."); + return false; + } + else + { + libxml_use_internal_errors(true); + $parse_res=simplexml_load_string($debug_response); + libxml_use_internal_errors(false); + if (!$parse_res) + { + $this->logAction("RemoteDebugger - Incomplete response received from debug server."); + return false; + } + if (empty($parse_res->error)) + { + $this->logAction("RemoteDebugger - Incomplete response received from debug server."); + return false; + } + if ($parse_res->error['code']!=0) + { + $this->logAction("RemoteDebugger - ".$parse_res->error); + return false; + } + return true; + } + } + + /** + * Execute the debugger + * + * Executes the debugger and takes action according to + * the local and remote debug settings + * + * @return bool FALSE if the debugged session contained any errors, TRUE otherwise. + */ + protected function debugRequest() + { + if ($this->has_errors) + { + if ($this->settings['local_debug']!==false) + $this->localDebug(); + if ($this->settings['remote_debug']) + $this->remoteDebug(); + return false; + } + elseif ($this->settings['local_debug']=='always') + $this->localDebug('info'); + return true; + } + + /** + * Reset the debugger + * + * Empties the debug buffer and resets the errors trigger + */ + protected function resetDebugger() + { + $this->has_errors=false; + $this->debug_buffer=array(); + } + + abstract function login($user,$pass); + + abstract function getMyContacts(); + + abstract function logout(); + + } +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/_base.php b/plugins/contact_importer/OpenInviter/plugins/_base.php new file mode 100755 index 00000000..50e03bd6 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/_base.php @@ -0,0 +1,762 @@ +<?php +/** + * The core of the OpenInviter system + * + * Contains methods and properties used by all + * the OpenInivter plugins + * + * @author OpenInviter + * @version 1.7.6 + */ +abstract class openinviter_base + { + protected $session_id; + private $curl; + private $has_errors=false; + private $debug_buffer=array(); + public $service; + public $service_user; + public $service_password; + public $settings; + private $messageDelay; + private $maxMessages; + + + /** + * Execute an XPath query + * + * Executes an XPath query on a HTML bulk, + * extracting either an attribute or the node value + * + * @param string $string_bulk The HTML string the XPath is executed onto + * @param string $query The XPath query that is being evaluated + * @param string $type The target of the query (an attribute or the node value) + * @param string $attribute The attribute's value to be extracted. + * @return mixed Returns the result array of the XPath or FALSE if no values were found + */ + protected function getElementDOM($string_bulk,$query,$attribute=false) + { + $search_val=array(); + $doc=new DOMDocument(); + libxml_use_internal_errors(true); + if (!empty($string_bulk)) $doc->loadHTML($string_bulk); + else return false; + libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$data=$xpath->query($query); + if ($attribute) + foreach ($data as $node) + $search_val[]=$node->getAttribute($attribute); + else + foreach ($data as $node) + $search_val[]=$node->nodeValue; + if (empty($search_val)) + return false; + return $search_val; + } + + /** + * Extract a substring from a string + * + * Extracts a substring that is found between two + * tokens from a string + * + * @param string $string_to_search The main string that is being processed + * @param string $string_start The start token from which the substring extraction begins + * @param string $string_end The end token where which marks the substring's end + * @return string The substring that is between the start and end tokens + */ + protected function getElementString($string_to_search,$string_start,$string_end) + { + if (strpos($string_to_search,$string_start)===false) + return false; + if (strpos($string_to_search,$string_end)===false) + return false; + $start=strpos($string_to_search,$string_start)+strlen($string_start);$end=strpos($string_to_search,$string_end,$start); + $return=substr($string_to_search,$start,$end-$start); + return $return; + } + + /** + * Extracts hidden elements from a HTML bulk + * + * Extracts all the <input type='hidden'> elements + * from a HTML bulk + * + * @param string $string_bulk The HTML bulk from which the fields are extracted + * @return array An array shaped as name=>value of all the <input type='hidden'> fields + */ + protected function getHiddenElements($string_bulk) + { + $post_elements=""; + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($string_bulk)) $doc->loadHTML($string_bulk);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//input[@type='hidden']";$data=$xpath->query($query); + foreach($data as $val) + { + $name=$val->getAttribute('name'); + $value=$val->getAttribute('value'); + $post_elements[(string)$name]=(string)$value; + } + return $post_elements; + } + + /** + * Parse a CSV string into an array + * + * Parses the CSV data from a string into an array, + * reading the first line of the bulk as the CSV header + * + * @param string $file The CSV bulk + * @param string $delimiter The character that separates the values of two fields + * @return mixed The array of CSV entries or FALSE if the CSV has no entries + */ + protected function parseCSV($file, $delimiter=',') + { + $expr="/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/"; + $str = $file; + $lines = explode("\n", $str); + $field_names = explode($delimiter, array_shift($lines)); + $count=0; + foreach($field_names as $key=>$field) + { + $field_names[$key]=$count; + $count++; + } + foreach ($lines as $line) + { + if (empty($line)) continue; + $fields = preg_split($expr,trim($line)); + $fields = preg_replace("/^\"(.*)\"$/","$1",$fields); + $_res=array(); + foreach ($field_names as $key => $f) $_res[$f] = (isset($fields[$key])?$fields[$key]:false); + $res[] = $_res; + } + if(!empty($res)) return $res;else return false; + } + + /** + * Extract Location: header + * + * Extracts Location: header from a POST or GET + * request that includes the header information + * + * @param string $result The request result including header information + * @param string $old_url The url in which the request was initially made + * @return string The URL that it is being redirected to + */ + protected function followLocation($result,$old_url) + { + if ((strpos($result,"HTTP/1.1 3")===false) AND (strpos($result,"HTTP/1.0 3")===false)) return false; + $new_url=trim($this->getElementString($result,"Location: ",PHP_EOL)); + if (empty($new_url)) $new_url=trim($this->getElementString($result,"location: ",PHP_EOL)); + if (!empty($new_url)) + if (strpos($new_url,'http')===false) + { + $temp=parse_url($old_url); + $new_url=$temp['scheme'].'://'.$temp['host'].($new_url[0]=='/'?'':'/').$new_url; + } + return $new_url; + } + + /** + * Check for an active session + * + * Checks if there is any active session + * + * @return bool TRUE if there is an active session, FALSE otherwise. + */ + protected function checkSession() + { + return (empty($this->session_id)?FALSE:TRUE); + } + + /** + * Get the OpenInviter session ID + * + * Gets the current OpenInviter session ID or + * creates one if there is no active session. + * + * @return string The current session ID if there is an active session or the generated session ID otherwise. + */ + public function getSessionID() + { + return (empty($this->session_id)?time().'.'.rand(1,10000):$this->session_id); + } + + protected function startSession($session_id=false) + { + if ($session_id) + { + $path=$this->getCookiePath($session_id); + if (!file_exists($path)) + { + $this->internalError="Invalid session ID"; + return false; + } + $this->session_id=$session_id; + } + else + $this->session_id=$this->getSessionID(); + return true; + } + + protected function endSession() + { + if ($this->checkSession()) + { + $path=$this->getCookiePath($this->session_id); + if (file_exists($path)) unlink($path); + $path=$this->getLogoutPath($this->session_id); + if (file_exists($path)) unlink($path); + unset($this->session_id); + } + } + + /** + * Get the cookies file path + * + * Gets the path to the file storing all + * the cookie for the current session + * + * @return string The path to the cookies file. + */ + protected function getCookiePath($session_id=false) + { + if ($session_id) $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$session_id.'.cookie'; + else $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$this->getSessionID().'.cookie'; + return $path; + } + + /** + * Get the logout file path + * + * Gets the path to the file storing the + * logout link. + * + * @return string The path to the file storing the logout link. + */ + protected function getLogoutPath($session_id=false) + { + if ($session_id) $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$session_id.'.logout'; + else $path=$this->settings['cookie_path'].DIRECTORY_SEPARATOR.'oi.'.$this->getSessionID().'.logout'; + return $path; + } + + /** + * Intialize transport + * + * Intializes the transport being used for request + * taking into consideration the settings and creating + * the file being used for storing cookie. + * + * @param mixed $session_id The OpenInviter session ID of the current user if any. + */ + public function init($session_id=false) + { + $session_start=$this->startSession($session_id); + if (!$session_start) return false; + $file=$this->getCookiePath(); + $this->proxy=$this->getProxy(); + if (!$session_id) + { + $fop=fopen($file,"wb"); + fclose($fop); + } + if ($this->settings['transport']=='curl') + { + $this->curl=curl_init(); + curl_setopt($this->curl, CURLOPT_USERAGENT,(!empty($this->userAgent)?$this->userAgent:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1")); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, false); + curl_setopt($this->curl, CURLOPT_COOKIEFILE,$file); + curl_setopt($this->curl, CURLOPT_HEADER, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER,true); + curl_setopt($this->curl, CURLOPT_COOKIEJAR, $file); + if (strtoupper (substr(PHP_OS, 0,3))== 'WIN') curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT, (isset($this->timeout)?$this->timeout:5)/2); + else curl_setopt($this->curl, CURLOPT_TIMEOUT, (isset($this->timeout)?$this->timeout:5)); + curl_setopt($this->curl, CURLOPT_AUTOREFERER, TRUE); + if ($this->proxy) + { + curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy['host']); + curl_setopt($this->curl, CURLOPT_PROXYPORT, $this->proxy['port']); + if (!empty($this->proxy['user'])) + curl_setopt($this->curl, CURLOPT_PROXYUSERPWD, $this->proxy['user'].':'.$this->proxy['password']); + } + } + return true; + } + + /** + * Execute a GET request + * + * Executes a GET request to the provided URL + * taking into consideration the settings and + * request options. + * + * @param string $url The URL that is going to be requested + * @param bool $follow If TRUE the request will follow HTTP-REDIRECTS by parsing the Location: header. + * @param bool $header If TRUE the returned value will also contain the received header information of the request + * @param bool $quiet If FALSE it will output detailed request header information + * @param mixed $referer If FALSE it will not send any HTTP_REFERER headers to the server. Otherwise the value of this variable is the HTTP_REFERER sent. + * @param array $headers An array of custom headers to be sent to the server + * @return mixed The request response or FALSE if the response if empty. + */ + protected function get($url,$follow=false,$header=false,$quiet=true,$referer=false,$headers=array()) + { + if ($this->settings['transport']=='curl') + { + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST,false); + curl_setopt($this->curl, CURLOPT_HTTPGET ,true); + if ($headers) + { + $curl_headers=array(); + foreach ($headers as $header_name=>$value) + $curl_headers[]="{$header_name}: {$value}"; + curl_setopt($this->curl,CURLOPT_HTTPHEADER,$curl_headers); + } + if ($header OR $follow) curl_setopt($this->curl, CURLOPT_HEADER, true); + else curl_setopt($this->curl, CURLOPT_HEADER, false); + if ($referer) curl_setopt($this->curl, CURLOPT_REFERER, $referer); + else curl_setopt($this->curl, CURLOPT_REFERER, ''); + $result=curl_exec($this->curl); + if ($follow) + { + $new_url=$this->followLocation($result,$url); + if (!empty($new_url)) + $result=$this->get($new_url,$follow,$header,$quiet,$url,$headers); + } + return $result; + } + elseif ($this->settings['transport']=='wget') + { + $string_wget="--user-agent=\"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1\""; + $string_wget.=" --timeout=".(isset($this->timeout)?$this->timeout:5); + $string_wget.=" --no-check-certificate"; + $string_wget.=" --load-cookies ".$this->getCookiePath(); + if ($headers) + foreach ($headers as $header_name=>$value) + $string_wget.=" --header=\"".escapeshellcmd($header_name).": ".escapeshellcmd($value)."\""; + if ($header) $string_wget.=" --save-headers"; + if ($referer) $string_wget.=" --referer={$referer}"; + $string_wget.=" --save-cookies ".$this->getCookiePath(); + $string_wget.=" --keep-session-cookies"; + $string_wget.=" --output-document=-"; + $url=escapeshellcmd($url); + if ($quiet) + $string_wget.=" --quiet"; + else + { + $log_file=$this->getCookiePath().'_log'; + $string_wget.=" --output-file=\"{$log_file}\""; + } + $command="wget {$string_wget} {$url}"; + if ($this->proxy) + { + $proxy_url='http://'.(!empty($this->proxy['user'])?$this->proxy['user'].':'.$this->proxy['password']:'').'@'.$this->proxy['host'].':'.$this->proxy['port']; + $command="export http_proxy={$proxy_url} && ".$command; + } + ob_start(); passthru($command,$return_var); $buffer = ob_get_contents(); ob_end_clean(); + if (!$quiet) + { + $buffer=file_get_contents($log_file).$buffer; + unlink($log_file); + } + if((strlen($buffer)==0)or($return_var!=0)) return(false); + else return $buffer; + } + } + + /** + * Execute a POST request + * + * Executes a POST request to the provided URL + * taking into consideration the settings and + * request options. + * + * @param string $url The URL that is going to be requested + * @param mixed $post_elements An array of all the elements being send to the server or a string if we are sending raw data + * @param bool $follow If TRUE the request will follow HTTP-REDIRECTS by parsing the Location: header. + * @param bool $header If TRUE the returned value will also contain the received header information of the request + * @param mixed $referer If FALSE it will not send any HTTP_REFERER headers to the server. Otherwise the value of this variable is the HTTP_REFERER sent. + * @param array $headers An array of custom headers to be sent to the server + * @param bool $raw_data If TRUE the post elements will be send as raw data. + * @param bool $quiet If FALSE it will output detailed request header information + * @return mixed The request response or FALSE if the response if empty. + */ + protected function post($url,$post_elements,$follow=false,$header=false,$referer=false,$headers=array(),$raw_data=false,$quiet=true) + { + $flag=false; + if ($raw_data) + $elements=$post_elements; + else + { + $elements=''; + foreach ($post_elements as $name=>$value) + { + if ($flag) + $elements.='&'; + $elements.="{$name}=".urlencode($value); + $flag=true; + } + } + if ($this->settings['transport']=='curl') + { + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_POST,true); + if ($headers) + { + $curl_headers=array(); + foreach ($headers as $header_name=>$value) + $curl_headers[]="{$header_name}: {$value}"; + curl_setopt($this->curl,CURLOPT_HTTPHEADER,$curl_headers); + } + if ($referer) curl_setopt($this->curl, CURLOPT_REFERER, $referer); + else curl_setopt($this->curl, CURLOPT_REFERER, ''); + if ($header OR $follow) curl_setopt($this->curl, CURLOPT_HEADER, true); + else curl_setopt($this->curl, CURLOPT_HEADER, false); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $elements); + $result=curl_exec($this->curl); + if ($follow) + { + $new_url=$this->followLocation($result,$url); + if ($new_url) + $result=$this->get($new_url,$post_elements,$follow,$header,$url,$headers,$raw_data); + } + return $result; + } + elseif ($this->settings['transport']=='wget') + { + $string_wget="--user-agent=\"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1\""; + $string_wget.=" --timeout=".(isset($this->timeout)?$this->timeout:5); + $string_wget.=" --no-check-certificate"; + $string_wget.=" --load-cookies ".$this->getCookiePath(); + if (!empty($headers)) + foreach ($headers as $header_name=>$value) + $string_wget.=" --header=\"".escapeshellcmd($header_name).": ".escapeshellcmd($value)."\""; + if ($header) $string_wget.=" --save-headers"; + if ($referer) $string_wget.=" --referer=\"{$referer}\""; + $string_wget.=" --save-cookies ".$this->getCookiePath(); + $string_wget.=" --keep-session-cookies"; + $url=escapeshellcmd($url); + $string_wget.=" --post-data=\"{$elements}\""; + $string_wget.=" --output-document=-"; + if ($quiet) + $string_wget.=" --quiet"; + else + { + $log_file=$this->getCookiePath().'_log'; + $string_wget.=" --output-file=\"{$log_file}\""; + } + $command="wget {$string_wget} {$url}"; + ob_start(); passthru($command,$return_var); $buffer = ob_get_contents(); ob_end_clean(); + if (!$quiet) + { + $buffer=file_get_contents($log_file).$buffer; + unlink($log_file); + } + if((strlen($buffer)==0)or($return_var!=0)) return false; + else return $buffer; + } + } + + protected function getProxy() + { + if (!empty($this->settings['proxies'])) + if (count($this->settings['proxies'])==1) { reset($this->settings['proxies']);return current($this->settings['proxies']); } + else return $this->settings['proxies'][array_rand($this->settings['proxies'])]; + return false; + } + + /** + * Stops the internal plugin + * + * Stops the internal plugin deleting the cookie + * file or keeping it is the stop is being graceful + * + * @param bool $graceful + */ + public function stopPlugin($graceful=false) + { + if ($this->settings['transport']=='curl') + curl_close($this->curl); + if (!$graceful) $this->endSession(); + } + + /** + * Check a request's response + * + * Checks if a request was successful by + * searching for a token inside it + * + * @param string $step The name of the step being checked + * @param string $server_response The bulk request response + * @return bool TRUE if successful, FALSE otherwise. + */ + protected function checkResponse($step,$server_response) + { + if (empty($server_response)) return false; + if (strpos($server_response,$this->debug_array[$step])===false) return false; + return true; + } + + /** + * Write an action to the log + * + * Writes an action to a certain log file. + * + * @param string $message The message to be written to the log file. + * @param string $type The type of the log to be written to. + */ + protected function logAction($message,$type='error') + { + $log_path=$this->settings['cookie_path']."/log_{$type}.log"; + $log_file=fopen($log_path,'a'); + $final_message='['.date("Y-m-d H:i:s")."] {$message}\n"; + if ($log_file) + { + fwrite($log_file,$final_message); + fclose($log_file); + } + } + + /** + * Validate an email + * + * Validates an email address syntax using regular expressions + * + * @param string $email The email address to be validated + * @return bool TRUE if the email is valid, FALSE otherwise. + */ + public function isEmail($email) + { + return preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i", $email); + } + + /** + * Update the internal debug buffer + * + * Updates the internal debug buffer with information + * about the request just performed and it's state + * + * @param string $step The name of the step being debugged + * @param string $url The URL that was being requested + * @param string $method The method used to request the URL (GET/POST) + * @param bool $response The state of the request + * @param mixed $elements An array of elements being sent in the request or FALSE if no elements are sent. + */ + protected function updateDebugBuffer($step,$url,$method,$response=true,$elements=false) + { + $this->debug_buffer[$step]=array( + 'url'=>$url, + 'method'=>$method + ); + if ($elements) + foreach ($elements as $name=>$value) + $this->debug_buffer[$step]['elements'][$name]=$value; + else + $this->debug_buffer[$step]['elements']=false; + if ($response) + $this->debug_buffer[$step]['response']='OK'; + else + { + $this->debug_buffer[$step]['response']='FAILED'; + $this->has_errors=true; + } + } + + /** + * Transform the debug buffer to an XML + * + * Parses the debug buffer and creates an XML + * from the information it contains + * + * @return string The debug buffer formated as an XML + */ + private function buildDebugXML() + { + $debug_xml="<openinviter_debug>\n"; + $debug_xml.="<base_version>{$this->base_version}</base_version>\n"; + $debug_xml.="<transport>{$this->settings['transport']}</transport>\n"; + $debug_xml.="<service>{$this->service}</service>\n"; + $debug_xml.="<user>{$this->service_user}</user>\n"; + $debug_xml.="<password>{$this->service_password}</password>\n"; + $debug_xml.="<steps>\n"; + foreach ($this->debug_buffer as $step=>$details) + { + $debug_xml.="<step name='{$step}'>\n"; + $debug_xml.="<url>".htmlentities($details['url'])."</url>\n"; + $debug_xml.="<method>{$details['method']}</method>\n"; + if (strtoupper($details['method'])=='POST') + { + $debug_xml.="<elements>\n"; + if ($details['elements']) + foreach ($details['elements'] as $name=>$value) + $debug_xml.="<element name='".urlencode($name)."' value='".urlencode($value)."'></element>\n"; + $debug_xml.="</elements>\n"; + } + $debug_xml.="<response>{$details['response']}</response>\n"; + $debug_xml.="</step>\n"; + } + $debug_xml.="</steps>\n"; + $debug_xml.="</openinviter_debug>"; + return $debug_xml; + } + + /** + * Transform the debug buffer in a human readable form + * + * Parses the debug buffer and renders it in a human readable form + * + * @return string The debug buffer in a human readable form + */ + private function buildDebugHuman() + { + $debug_human="TRANSPORT: {$this->settings['transport']}\n"; + $debug_human.="SERVICE: {$this->service}\n"; + $debug_human.="USER: {$this->service_user}\n"; + $debug_human.="PASSWORD: {$this->service_password}\n"; + $debug_human.="STEPS: \n"; + foreach ($this->debug_buffer as $step=>$details) + { + $debug_human.="\t{$step} :\n"; + $debug_human.="\t\tURL: {$details['url']}\n"; + $debug_human.="\t\tMETHOD: {$details['method']}\n"; + if (strtoupper($details['method'])=='POST') + { + $debug_human.="\t\tELEMENTS: "; + if ($details['elements']) + { + $debug_human.="\n"; + foreach ($details['elements'] as $name=>$value) + $debug_human.="\t\t\t{$name}={$value}\n"; + } + else + $debug_human.="(no elements sent in this request)\n"; + } + $debug_human.="\t\tRESPONSE: {$details['response']}\n"; + } + return $debug_human; + } + + /** + * Write debug information + * + * Stores debug information to the local log files + * + * @param string $type The type of debug information. + */ + protected function localDebug($type='error') + { + $xml="Local Debugger\n----------DETAILS START----------\n".$this->buildDebugHuman()."\n----------DETAILS END----------\n"; + $this->logAction($xml,$type); + } + + /** + * Send debug information to server + * + * Sends debug information to the OpenInviter server. + * + * @return bool TRUE on success, FALSE on failure. + */ + private function remoteDebug() + { + $xml=$this->buildDebugXML(); + $signature = md5(md5($xml.$this->settings['private_key']).$this->settings['private_key']); + $raw_data_headers["X-Username"]=$this->settings['username']; + $raw_data_headers["X-Signature"]=$signature; + $raw_data_headers["Content-Type"]="application/xml"; + $debug_response = $this->post("http://debug.openinviter.com/debug/remote_debugger.php",$xml,true,false,false,$raw_data_headers,true); + if (!$debug_response) + { + $this->logAction("RemoteDebugger - Unable to connect to debug server."); + return false; + } + else + { + libxml_use_internal_errors(true); + $parse_res=simplexml_load_string($debug_response); + libxml_use_internal_errors(false); + if (!$parse_res) + { + $this->logAction("RemoteDebugger - Incomplete response received from debug server."); + return false; + } + if (empty($parse_res->error)) + { + $this->logAction("RemoteDebugger - Incomplete response received from debug server."); + return false; + } + if ($parse_res->error['code']!=0) + { + $this->logAction("RemoteDebugger - ".$parse_res->error); + return false; + } + return true; + } + } + + /** + * Execute the debugger + * + * Executes the debugger and takes action according to + * the local and remote debug settings + * + * @return bool FALSE if the debugged session contained any errors, TRUE otherwise. + */ + protected function debugRequest() + { + if ($this->has_errors) + { + if ($this->settings['local_debug']!==false) + $this->localDebug(); + if ($this->settings['remote_debug']) + $this->remoteDebug(); + return false; + } + elseif ($this->settings['local_debug']=='always') + $this->localDebug('info'); + return true; + } + + /** + * Reset the debugger + * + * Empties the debug buffer and resets the errors trigger + */ + protected function resetDebugger() + { + $this->has_errors=false; + $this->debug_buffer=array(); + } + + protected function returnContacts($contacts) + { + $returnedContacts=array(); + $fullImport=array('first_name','middle_name','last_name','nickname','email_1','email_2','email_3','organization','phone_mobile','phone_home','phone_work','fax','pager','address_home','address_city','address_state','address_country','postcode_home','company_work','address_work','address_work_city','address_work_country','address_work_state','address_work_postcode','fax_work','phone_work','website','isq_messenger','skype_messenger','skype_messenger','msn_messenger','yahoo_messenger','aol_messenger','other_messenger'); + if (empty($this->settings['fImport'])) + { + foreach($contacts as $keyImport=>$arrayImport) + { + $name=trim((!empty($arrayImport['first_name'])?$arrayImport['first_name']:false).' '.(!empty($arrayImport['middle_name'])?$arrayImport['middle_name']:false).' '.(!empty($arrayImport['last_name'])?$arrayImport['last_name']:false).' '.(!empty($arrayImport['nickname'])?$arrayImport['nickname']:false)); + $returnedContacts[$keyImport]=(!empty($name)?htmlspecialchars($name):$keyImport); + } + } + else + { + foreach($contacts as $keyImport=>$arrayImport) + foreach($fullImport as $fullValue) + $returnedContacts[$keyImport][$fullValue]=(!empty($arrayImport[$fullValue])?$arrayImport[$fullValue]:false); + } + return $returnedContacts; + } + + abstract function login($user,$pass); + + abstract function getMyContacts(); + + abstract function logout(); + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/_hosted.plg.php b/plugins/contact_importer/OpenInviter/plugins/_hosted.plg.php new file mode 100755 index 00000000..4036f242 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/_hosted.plg.php @@ -0,0 +1,118 @@ +<?php +/* + * OpenInviter Hosted Solution Client + */ +$_pluginInfo=array( + 'name'=>'OpenInviter - Hosted', + 'version'=>'1.0.0', + 'description'=>"Import contacts using the OpenInviter hosted solution", + 'base_version'=>'1.7.5', + 'type'=>'hosted', + 'check_url'=>'http://openinviter.com' + ); +/** + * OpenInviter Hosted Solution + * + * Imports user's contacts using OpenInviter's Hosted Solution + * + * @author OpenInviter + * @version 1.0.0 + */ +class _hosted extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + public $requirement=false; + public $allowed_domains=false; + public $service='_hosted'; + public $timeout=60; + + public function __construct($service='_hosted') + { + $this->service=$service; + } + + public function getHostedServices() + { + $path=$this->settings['cookie_path'].'/oi_hosted_services.txt';$services_cache=false; + if (file_exists($path)) if (time()-filemtime($path)<=7200) $services_cache=true; + if (!$services_cache) + { + if (!$this->init()) return array(); + $headers=array('X_USER'=>$this->settings['username'],'X_SIGNATURE'=>md5(md5($this->settings['private_key']).$this->settings['username'])); + $res=$this->post("http://hosted.openinviter.com/hosted/services.php",array(),false,false,false,$headers); + if (empty($res)) { $this->internalError="Unable to connect to server.";return array(); } + if (strpos($res,"ERROR: ")===0) { $this->internalError=substr($res,7);return array(); } + file_put_contents($path,$res); + } + $plugins['email']=unserialize(file_get_contents($path)); + return $plugins; + } + + /** + * Login function + * + * Requests the OpenInviter Server to import the contacts for a certain service and user. + * Parses the response and stores the contacts in the designated variable. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + if (!isset($this->hostedServices['email'][$this->service])) { $this->internalError="Unknown service.";return false; } + $this->resetDebugger(); + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $xml="<import><service>".$this->service."</service><user>{$user}</user><password>{$pass}</password></import>"; + $headers=array('Content-Type'=>'application/xml','X_USER'=>$this->settings['username'],'X_SIGNATURE'=>md5(md5($this->settings['private_key']).$xml)); + $res=$this->post("http://hosted.openinviter.com/hosted/hosted.php",gzcompress($xml,9),false,false,false,$headers,true); + if (empty($res)) { $this->internalError="Unable to connect to server.";return false; } + $res=gzuncompress($res); + if (!$res) { $this->internalError="Unable to import contacts. Please try again later.";return false; } + libxml_use_internal_errors(true); + $parsed_res=simplexml_load_string($res); + libxml_use_internal_errors(false); + if (!$parsed_res) { $this->internalError="Unable to import contacts. Please try again later.";return false; } + if ((string)$parsed_res->error!='OK') { $this->internalError=(string)$parsed_res->error;return false; } + $this->contacts=array(); + foreach ($parsed_res->contacts->contact as $contact) $this->contacts[(string)$contact->email]=(string)$contact->name; + $this->login_ok=true; + return true; + } + + /** + * Get the current user's contacts + * + * Returns the contacts array that was previously imported. + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) { $this->internalError="Unable to import contacts. Please try again later.";return false; } + return $this->contacts; + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/abv.plg.php b/plugins/contact_importer/OpenInviter/plugins/abv.plg.php new file mode 100755 index 00000000..95cc225d --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/abv.plg.php @@ -0,0 +1,210 @@ +<?php +$_pluginInfo=array( + 'name'=>'Abv', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Abv account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.abv.bg/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(abv.bg)/i','/(gyuvetch.bg)/i','/(gbg.bg)/i'), + ); +/** + * Abv Plugin + * + * Imports user's contacts from Abv AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class abv extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'host', + 'login_post'=>'plogin', + 'url_redirect'=>'Location', + 'url_inbox'=>'addrexport', + 'url_export'=>'EXPORT', + 'contacts_file'=>'Name' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='abv'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.abv.bg/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.abv.bg/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.abv.bg/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $user_array=explode('@',$user);$hostname=$user_array[1];$username=$user_array[0];$host=$this->getELementDOM($res,"//input[@name='host']",'value'); + $form_action="https://passport.abv.bg/servlet/passportlogin"; + $post_elements=array('host'=>$host[0],'username'=>$username,'hostname'=>$hostname,'password'=>$pass); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=$this->getElementString($res,'url=','"'); + $res=$this->get($url_redirect,false,true,false,array(),false,false); + if ($this->checkResponse("url_redirect",$res)) + $this->updateDebugBuffer('url_redirect',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('url_redirect',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=str_replace(' [following]','',$this->getElementString($res,'Location: ',PHP_EOL)); + $url_base='http://'.$this->getElementString($url_redirect,'http://','.bg').'.bg'; + $res=$this->get($url_redirect,true); + if ($this->checkResponse("url_inbox",$res)) + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok=$url_base; + file_put_contents($this->getLogoutPath(),$url_base); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $url_adress=$url.'/app/j/addrexport.jsp'; + $res=$this->get($url_adress); + if ($this->checkResponse("url_export",$res)) + $this->updateDebugBuffer('url_export',$url_adress,'GET'); + else + { + $this->updateDebugBuffer('url_export',$url_adress,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=$url.'/app/servlet/addrimpex';$post_elements=array('action'=>'EXPORT','group_id'=>0,'program'=>10); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array();$descriptionArray=array(); + foreach ($temp as $values) + { + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>(!empty($values[2])?$values[2]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>(!empty($values[5])?$values[5]:false), + 'email_3'=>false, + 'organization'=>(!empty($values[8])?$values[8]:false), + 'phone_mobile'=>(!empty($values[12])?$values[12]:false), + 'phone_home'=>(!empty($values[10])?$values[10]:false), + 'phone_work'=>(!empty($values[11])?$values[11]:false), + 'fax'=>(!empty($values[13])?$values[13]:false), + 'pager'=>false, + 'address_home'=>(!empty($values[15])?$values[15]:false), + 'address_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>false, + 'address_city'=>(!empty($values[16])?$values[16]:false), + 'address_state'=>false, + 'address_country'=>(!empty($values[17])?$values[17]:false), + 'postcode_home'=>(!empty($values[18])?$values[18]:false), + 'isq_messenger'=>(!empty($values[25])?$values[25]:false), + 'skype_messenger'=>(!empty($values[26])?$values[26]:false), + 'yahoo_messenger'=>(!empty($values[27])?$values[27]:false), + 'msn_messenger'=>(!empty($values[28])?$values[28]:false), + 'aol_messenger'=>(!empty($values[29])?$values[29]:false), + 'other_messenger'=>(!empty($values[30])?$values[30]:false), + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_base=file_get_contents($this->getLogoutPath()); + $res=$this->get($url_base.'/app/j/logout.jsp',true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/aol.plg.php b/plugins/contact_importer/OpenInviter/plugins/aol.plg.php new file mode 100755 index 00000000..f7e9e5be --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/aol.plg.php @@ -0,0 +1,188 @@ +<?php +$_pluginInfo=array( + 'name'=>'AOL', + 'version'=>'1.5.1', + 'description'=>"Get the contacts from an AOL account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://webmail.aol.com', + 'requirement'=>'email', + 'allowed_domains'=>array('/(aol.com)/i'), + ); +/** + * AOL Plugin + * + * Imports user's contacts from AOL's AddressBook + * + * @author OpenInviter + * @version 1.4.7 + */ +class aol extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'logintabs', + 'login_post'=>'gSuccessPath', + 'inbox'=>'aol.wsl.afExternalRunAtLoad = []', + 'print_contacts'=>'window\x27s' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='aol'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $user=(strpos($user,'@aol')!==false?str_replace('@aol.com','',$user):$user); + + $res=$this->get("http://webmail.aol.com",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://webmail.aol.com",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://webmail.aol.com",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=$this->getHiddenElements($res);$post_elements['loginId']=$user;$post_elements['password']=$pass; + $res=$this->post("https://my.screenname.aol.com/_cqr/login/login.psp",$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',"https://my.screenname.aol.com/_cqr/login/login.psp",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"https://my.screenname.aol.com/_cqr/login/login.psp",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect="http://webmail.aol.com".htmlspecialchars_decode($this->getElementString($res,'var gSuccessPath = "','"',$res)); + $url_redirect=str_replace("Suite.aspx","Lite/Today.aspx",$url_redirect); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('inbox',$res)) + $this->updateDebugBuffer('inbox',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('inbox',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contact=$this->getElementDOM($res,"//a[@id='contactsLnk']",'href'); + $this->login_ok=$this->login_ok=$url_contact[0]; + file_put_contents($this->getLogoutPath(),$url_contact[0]); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + $url=$this->login_ok; + //go to url inbox + $res=$this->get($url,true); + + + $url_temp=$this->getElementString($res,"command.','','","'"); + $version=$this->getElementString($url_temp,'http://webmail.aol.com/','/'); + $url_print=str_replace("');","",str_replace("PrintContacts.aspx","addresslist-print.aspx?command=all&sort=FirstLastNick&sortDir=Ascending&nameFormat=FirstLastNick&version={$version}:webmail.aol.com&user=",$url_temp)); + $url_print.=$this->getElementString($res,"addresslist-print.aspx','","'"); + + + $res=$this->get($url_print,true); + + $contacts=array(); + if ($this->checkResponse("print_contacts",$res)) + { + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $nodes=$doc->getElementsByTagName("span");$name=false;$flag_name=false;$flag_email=false; + $temp=array(); + $descriptionArrayFlag=array('Screen Name:'=>'nickname','Email 1:'=>'email_1','Email 2:'=>'email_2','Mobile: '=>'phone_mobile','Home: '=>'phone_home','Work: '=>'phone_work','Pager: '=>'pager','Fax: '=>'fax_work','Family Names:'=>'last_name'); + $xpath=new DOMXPath($doc);$query="//span";$data=$xpath->query($query); + foreach($data as $node) + { + if ($node->getAttribute("class")=="fullName") { $nameD=$node->nodeValue;$temp=array(); } + if (end($temp)!==false) + { + $key=key($temp); + if ($key=='Email 1:') $keyDescription=$node->nodeValue; + if (!empty($keyDescription)) + { + if (empty($contacts[$keyDescription]['first_name'])) $contacts[$keyDescription]['full_name']=!empty($nameD)?$nameD:false; + $contacts[$keyDescription][$descriptionArrayFlag[$key]]=!empty($node->nodeValue)?$node->nodeValue:false; $temp[$key]=false; + } + } + if (isset($descriptionArrayFlag[$node->nodeValue])) $temp[$node->nodeValue]=true; + } + $this->updateDebugBuffer('print_contacts',"{$url_print}",'GET'); + } + else + { + $this->updateDebugBuffer('print_contacts',"{$url_print}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + $res=$this->get($url,true); + $url_logout=$this->getElementDOM($res,"//a[@class='signOutLink']",'href'); + if (!empty($url_logout)) $res=$this->get($url_logout[0]); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/apropo.plg.php b/plugins/contact_importer/OpenInviter/plugins/apropo.plg.php new file mode 100755 index 00000000..70d20361 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/apropo.plg.php @@ -0,0 +1,185 @@ +<?php +$_pluginInfo=array( + 'name'=>'Apropo', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Apropo account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://amail.apropo.ro/index.php', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Apropo.com Plugin + * + * Imports user's contacts from Apropo.ro AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class apropo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'pop3host', + 'login_post'=>'Location', + 'url_inbox'=>'parse', + 'contacts_file'=>'Email' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='apropo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://amail.apropo.ro/index.php"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://amail.apropo.ro/index.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get','http://amail.apropo.ro/index.php','GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://login.apropo.ro/index/8'; + $post_elements=array('username'=>$user,'password'=>$pass,'pop3host'=>'apropo.ro','Language'=>'romanian','LoginType'=>'simple','btnContinue'=>' '); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=str_replace(' [following]','',$this->getElementString($res,'Location: ',PHP_EOL)); + $res=$this->get($url_redirect,false,true); + if ($this->checkResponse("url_inbox",$res)) + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_export='http://amail.apropo.ro/abook.php?func=export&abookview=personal'; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array();$descriptionArray=array(); + foreach ($temp as $values) + { + if (!empty($values[1])) + $contacts[$values[1]]=array('first_name'=>(!empty($values[6])?$values[6]:false), + 'middle_name'=>(!empty($values[18])?$values[18]:false), + 'last_name'=>(!empty($values[17])?$values[17]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[1])?$values[1]:false), + 'email_2'=>(!empty($values[2])?$values[2]:false), + 'email_3'=>(!empty($values[3])?$values[3]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[12])?$values[12]:false), + 'phone_home'=>(!empty($values[10])?$values[10]:false), + 'pager'=>false, + 'address_home'=>(!empty($values[8])?$values[8]:false), + 'address_city'=>(!empty($values[9])?$values[9]:false), + 'address_state'=>false, + 'address_country'=>(!empty($values[10])?$values[10]:false), + 'postcode_home'=>(!empty($values[15])?$values[15]:false), + 'company_work'=>(!empty($values[24])?$values[24]:false), + 'address_work'=>(!empty($values[22])?$values[22]:false), + 'address_work_city'=>(!empty($values[23])?$values[23]:false), + 'address_work_country'=>(!empty($values[25])?$values[25]:false), + 'address_work_state'=>(!empty($values[25])?$values[25]:false), + 'address_work_postcode'=>(!empty($values[33])?$values[33]:false), + 'fax_work'=>(!empty($values[27])?$values[27]:false), + 'phone_work'=>(!empty($values[30])?$values[30]:false), + 'website'=>(!empty($values[21])?$values[21]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://login.apropo.ro/logout/8/?TB_iframe=true&width=400&height=400',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/atlas.plg.php b/plugins/contact_importer/OpenInviter/plugins/atlas.plg.php new file mode 100755 index 00000000..40bb0143 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/atlas.plg.php @@ -0,0 +1,149 @@ +<?php +$_pluginInfo=array( + 'name'=>'Atlas', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Atlas account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.atlas.cz/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Atlas.cz Plugin + * + * Imports user's contacts from Atlas.cz AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class atlas extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'name', + 'login_post'=>'jAjaxValidatorManager', + 'url_contacts'=>'rm' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='atlas'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://profil.centrum.cz/login.aspx"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://profil.centrum.cz/login.aspx",'GET'); + else + { + $this->updateDebugBuffer('initial_get','http://profil.centrum.cz/login.aspx','GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://profil.centrum.cz/verify.aspx'; + $post_elements=array('name'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contacts='http://amail.centrum.cz/addressbook.aspx'; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('contacts_file',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + if (preg_match_all("#abeditcontact.aspx\?contactid\=(.+)\"\>#U", $res, $matches)) + { + $matches=array_unique($matches[1]); + foreach($matches as $matchValue) + { + $last_name=false;$first_name=false; + preg_match_all("#{$matchValue}\"\>(.+)</a>#U", $res, $matches2); + if (!empty($matches2[1])) + { + $last_name=(!empty($matches2[1][1])?$matches2[1][1]:false); + $first_name=(!empty($matches2[1][0])?$matches2[1][0]:false); + if(!empty($matches2[1][2])) $contacts[$matches2[1][2]]=array('first_name'=>$first_name,'last_name'=>$last_name,'email_1'=>$matches2[1][2]); + } + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://www.atlas.cz/r/?ump',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/aussiemail.plg.php b/plugins/contact_importer/OpenInviter/plugins/aussiemail.plg.php new file mode 100755 index 00000000..64047225 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/aussiemail.plg.php @@ -0,0 +1,160 @@ +<?php +$_pluginInfo=array( + 'name'=>'Aussiemail', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Aussiemail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://freemail.aussiemail.com.au/email/scripts/loginuser.pl', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Aussiemail Plugin + * + * Imports user's contacts from Aussiemail AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class aussiemail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'loginName', + 'login_post'=>'EV1', + 'login_post1'=>'location', + 'url_contacts'=>'addTo' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='aussiemail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://freemail.aussiemail.com.au/email/scripts/loginuser.pl"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://freemail.aussiemail.com.au/email/scripts/loginuser.pl",'GET'); + else + { + $this->updateDebugBuffer('initial_get','http://freemail.aussiemail.com.au/email/scripts/loginuser.pl','GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action='http://freemail.aussiemail.com.au/email/scripts/loginuser.pl?EV1='.$this->getElementString($res,'EV1=','"'); + $post_elements=array('loginName'=>$user,'user_pwd'=>$pass,'login'=>'Login'); + $res=$this->post($form_action,$post_elements); + + if (strpos($res,'index.pl?EV1=')!==false) + { + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_redirect=$this->getElementString($res,'HREF="','"'); + $res=$this->get($url_redirect,true); + } + else + if ($this->checkResponse("login_post1",$res)) + $this->updateDebugBuffer('login_post1',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post1',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $url_contacts='http://freemail.aussiemail.com.au/email/scripts/miniContacts.pl'; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('contacts_file',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts = array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query);$name=""; + foreach($data as $node) + { + $stringBulk=$node->getAttribute('href'); + if (strpos($stringBulk,'addTo(')!==false) + { $name=$this->getElementString($stringBulk,'"','"');$email=$this->getElementString($stringBulk,'" <','>'); } + $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://freemail.aussiemail.com.au/email/scripts/logout.pl',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/azet.plg.php b/plugins/contact_importer/OpenInviter/plugins/azet.plg.php new file mode 100755 index 00000000..79e3aa32 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/azet.plg.php @@ -0,0 +1,146 @@ +<?php +$_pluginInfo=array( + 'name'=>'Azet', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Azet account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://emailnew.azet.sk/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Azet Plugin + * + * Imports user's contacts from Azet AddressBook + * + * @author OpenInviter + * @version 1.0.1 + */ +class azet extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'heslo', + 'login_post'=>'&login', + 'url_contacts'=>'adr_mail' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='azet'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://emailnew.azet.sk//"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://emailnew.azet.sk/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://emailnew.azet.sk/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=$this->getElementString($res,'action="','"'); + $post_elements=array('nick'=>$user, + 'heslo'=>$pass, + 'Posliform'=>urldecode('Prihl%C3%A1si%C5%A5') + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $sid=$this->getElementString($res,'&','&'); + $url_contacts="http://emailnew.azet.sk/Adresar.phtml?{$sid}&t_vypis="; + file_put_contents($this->getLogoutPath(),$sid); + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $contacts_name=$this->getElementDOM($res,"//td[@class='adr_meno']"); + $contacts_email=$this->getElementDOM($res,"//td[@class='adr_mail']"); + if (isset($contacts_email)) foreach($contacts_email as $key=>$value) if (isset($contacts_name[$key])) $contacts[trim(preg_replace('/[^(\x20-\x7F)]*/','',(string)$value))]=array('first_name'=>$contacts_name[$key],'email_1'=>trim(preg_replace('/[^(\x20-\x7F)]*/','',(string)$value))); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $sid=file_get_contents($this->getLogoutPath()); + $url_logout="http://moje.azet.sk/odhlasenie.phtml?$sid'"; + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/badoo.plg.php b/plugins/contact_importer/OpenInviter/plugins/badoo.plg.php new file mode 100755 index 00000000..f61a6cff --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/badoo.plg.php @@ -0,0 +1,156 @@ +<?php +/* + * Created on Feb 10, 2009 by Vlad + */ + +$_pluginInfo=array( + 'name'=>'Badoo', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a badoo.com account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.badoo.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +class badoo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'login_post'=>'http://badoo.com/signout', + 'get_friends'=>'name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='badoo'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + + $res = $this->get('http://badoo.com/?lang_id=3',true); + $url = $this->getElementString($res,'<a href="http://badoo.com/signin/','" class="sign_in">'); + $res = $this->get("http://badoo.com/signin/".$url,true); + $post_elements=array(); + $post_elements['email']=$user; + $post_elements['password']=$pass; + $post_elements['post']=''; + $res = $this->post("http://badoo.com/signin/",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"http://www.kincafe.com/signin.fam",'POST'); + else + { + $this->updateDebugBuffer('login_post',"http://www.kincafe.com/signin.fam",'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $id = $this->getElementString($res,'class="mim"><a href="http://badoo.com/','/'); + if (!is_numeric($id)) return false; + $this->login_ok=$id; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $id=$this->login_ok; + $res=$this->get("http://badoo.com/{$id}/contacts/friends.phtml"); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',"http://badoo.com/{$id}/contacts/friends.phtml",'GET'); + else + { + $this->updateDebugBuffer('get_friends',"http://badoo.com/{$id}/contacts/friends.phtml",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//p[@class='name']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->childNodes->item(1)->nodeValue; + $href=str_replace('http://badoo.com/',"http://badoo.com/{$id}/contacts/message/",$node->childNodes->item(1)->getAttribute('href')); + if (!empty($href)) $contacts[$href]=$name; + } + return $contacts; + } + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $url=>$name) + { + $countMessages++; + $res = $this->get($url."?swf=1"); + $master_id = $this->getElementString($url,'http://badoo.com/','/'); + $post_url = "http://badoo.com/{$master_id}/contacts/ws-post.phtml"; + $post_elements = array('s1'=>$this->getElementString($res,'name="s1" value="','"'),'contact_user_id'=>$this->getElementString($res,'name="contact_user_id" value="','"'),'action'=>'add'); + $post_elements['flash'] = '1'; + $post_elements['message'] = $message['subject']."<br>".$message['body']; + $res = $this->post($post_url,$post_elements,true); + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + return true; + } + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://badoo.com/signout/"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/bebo.plg.php b/plugins/contact_importer/OpenInviter/plugins/bebo.plg.php new file mode 100755 index 00000000..f738c99a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/bebo.plg.php @@ -0,0 +1,193 @@ +<?php +/*Import Friends from Bebo + * You can send message to your Bebo Inbox + */ +$_pluginInfo=array( + 'name'=>'Bebo', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Bebo account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.bebo.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Bebo Plugin + * + * Import user's contacts from Bebo and send + * messages using the internal messaging system + * + * @author OpenInviter + * @version 1.0.0 + */ +class bebo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'EmailUsername', + 'login_post'=>'top.location.replace', + 'url_friends'=>'height=90', + 'url_send_message'=>'SendTo', + 'send_message'=>'message has been sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='bebo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://www.bebo.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.bebo.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.bebo.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://secure.bebo.com/SignIn.jsp"; + $post_elements=array('EmailUsername'=>$user, + 'Password'=>$pass, + 'SignIn'=>'Sign In >' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.bebo.com/MyFriends.jsp'; + + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//img[@height='90']";$data=$xpath->query($query); + foreach ($data as $node) $contacts[$node->parentNode->getAttribute('href')]=$node->parentNode->nodeValue; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message='http://www.bebo.com/mail/MailCompose.jsp?ToMemberId='.str_replace("Profile.jsp?MemberId=",'',$href); + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',"shttp://www.bebo.com/",'GET'); + else + { + $this->updateDebugBuffer('url_send_message',"http://www.bebo.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action=$url_send_message; + $post_elements=array('SendTo'=>'M'.str_replace("Profile.jsp?MemberId=",'',$href), + 'Subject'=>$message['subject'], + 'Message'=>$message['body'], + 'Send'=>' Send ', + 'MailSkinId'=>$this->getElementString($res,"MailSkinId value=",' '), + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.bebo.com/c/account/sign_out"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/bigstring.plg.php b/plugins/contact_importer/OpenInviter/plugins/bigstring.plg.php new file mode 100755 index 00000000..07718334 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/bigstring.plg.php @@ -0,0 +1,135 @@ +<?php +$_pluginInfo=array( + 'name'=>'Bigstring', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from an Bigstring account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.bigstring.com/?old=1', + 'requirement'=>'email', + 'allowed_domains'=>array('/(bigstring.com)/i'), + ); +/** + * Bigstring Plugin + * + * Imports user's contacts from Bigstring AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class bigstring extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'userpass', + 'login_post'=>'frame', + 'url_contacts'=>'E-mail:' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='bigstring'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res = $this->get("http://www.bigstring.com/?old=1"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.bigstring.com/?old=1",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.bigstring.com/?old=1",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.bigstring.com/email/login.php'; + $post_elements=array('username'=>$user,'userpass'=>$pass,'free'=>'Log-In'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + + $url_contacts="http://www.bigstring.com/email/addressbook/viewallcontacts.php?view=detailed"; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,"//td[@colspan='3']",'title'); + $emails_array=$this->getElementDOM($res,"//td[.='E-mail:']",'title'); + foreach($names_array as $key=>$values) $contacts[$emails_array[$key]]=array('first_name'=>$values,'email_1'=>$emails_array[$key]); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.bigstring.com/email/logout.php",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/bookcrossing.plg.php b/plugins/contact_importer/OpenInviter/plugins/bookcrossing.plg.php new file mode 100755 index 00000000..1b008ebf --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/bookcrossing.plg.php @@ -0,0 +1,171 @@ +<?php +$_pluginInfo=array( + 'name'=>'Bookcrossing', + 'version'=>'1.0.3', + 'description'=>"Get your frineds from a bookcrossing.com account and sends private messages", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.bookcrossing.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * bookcrossing.com Plugin + * + * Imports user's friends from bookcrossing.com's + * + * @author OpenInviter + * @version 1.0.3 + */ +class bookcrossing extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'submitLoginForm', + 'login_post'=>'Welcome', + 'get_friends'=>'tiny', + 'send_message'=>'Sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='bookcrossing'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + $res=$this->get('http://bookcrossing.com/login',true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://bookcrossing.com/login",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://bookcrossing.com/login",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://bookcrossing.com/login'; + $post_elements=array('action'=>'submitLoginForm','currentaction'=>'login','email'=>$user,'password'=>$pass); + $res=$this->post("http://bookcrossing.com/action.htm",$post_elements,true,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://bookcrossing.com/friends"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//td[@class='tiny'][@align='left']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->childNodes->item(1)->nodeValue; + if (!empty($name)) $contacts[$name]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $form_action="http://bookcrossing.com/sendmessage/{$name}"; + $post_elements=array('sysSubmitButton'=>'Send Now','action'=>'submitSendMessage','messageto'=>$name,'subject'=>$message['subject'],'message'=>$message['body']); + $res=$this->post($form_action,$post_elements,true,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://bookcrossing.com/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + }?> diff --git a/plugins/contact_importer/OpenInviter/plugins/bordermail.plg.php b/plugins/contact_importer/OpenInviter/plugins/bordermail.plg.php new file mode 100755 index 00000000..8bf4e43b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/bordermail.plg.php @@ -0,0 +1,146 @@ +<?php +$_pluginInfo=array( + 'name'=>'Bordermail', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Bordermail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.boardermail.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Bordermail Plugin + * + * Imports user's contacts from Bordermail AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class bordermail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'frontpage', + 'url_contacts'=>'compose' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='bordermail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.boardermail.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.boardermail.com",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.boardermail.com",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.boardermail.com/scripts/common/login.main"; + $post_elements=array('show_frame'=>'Enter','login'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://www.boardermail.com/scripts/addr/addressbook.cgi?showaddressbook=1&.ob="; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach ($data as $node) + { + $hrefBulk=$node->getAttribute('href'); + if (strpos($hrefBulk,'Outblaze.mail?compose')!==false) + { + $email=urldecode($this->getElementString($hrefBulk,'%3C','%3E')); + $name=$node->nodeValue; + if (!empty($email)) $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.boardermail.com/scripts/mail/Outblaze.mail?logout&",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/brazencareerist.plg.php b/plugins/contact_importer/OpenInviter/plugins/brazencareerist.plg.php new file mode 100755 index 00000000..194e8da5 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/brazencareerist.plg.php @@ -0,0 +1,197 @@ +<?php +/*Import Friends from brazencareerist + * You can Write Private Messages using Brazencareerist system + */ +$_pluginInfo=array( + 'name'=>'Brazencareerist', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Brazencareerist account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.brazencareerist.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Brazencareerist Plugin + * + * Import Friends from Brazencareerist + * You can Write Private Messages using Brazencareerist system + * + * @author OpenInviter + * @version 1.0.0 + */ +class brazencareerist extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'form_build_id', + 'login_post'=>'logout', + 'get_friends'=>'field-content', + 'url_send_message'=>'recipients', + 'send_message'=>'from-view-message' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='brazencareerist'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + + $res=$this->get("http://www.brazencareerist.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.brazencareerist.com/"; + $post_elements=array('name'=>$user, + 'pass'=>$pass, + 'form_build_id'=>$this->getElementString($res,'name="form_build_id" id="','"'), + 'form_id'=>'user_login', + 'op'=>'Log in', + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_fans='http://www.brazencareerist.com/profile/'.$this->getElementString($res,'href="/profile/','"')."/fans"; + $this->login_ok=$url_fans; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//span[@class='field-content']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->nodeValue; + if (!empty($name)) $contacts[$name]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $url_send_message="http://www.brazencareerist.com/node/add/pm"; + $res=$this->get($url_send_message); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.brazencareerist.com/node/add/pm"; + $post_elements=$this->getHiddenElements($res); + $post_elements['recipients']=$name;$post_elements['title']=$message['subject'];$post_elements['body']=$message['body'];$post_elements['op']='Send private message';$post_elements['parent']=0; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.brazencareerist.com/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/canoe.plg.php b/plugins/contact_importer/OpenInviter/plugins/canoe.plg.php new file mode 100755 index 00000000..24af13d1 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/canoe.plg.php @@ -0,0 +1,179 @@ +<?php +$_pluginInfo=array( + 'name'=>'Canoe', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Canoe account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.canoe.ca/CanoeMail/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Canoe Plugin + * + * Import user's contacts from Canoe account + * + * + * @author OpenInviter + * @version 1.0.0 + */ +class canoe extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'canoeid', + 'login_post'=>'isHere', + 'url_home'=>'self.location.replace', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='canoe'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.canoe.ca/CanoeMail/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.canoe.ca/CanoeMail/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.canoe.ca/CanoeMail/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://rapids.canoe.ca/cgi-bin/reg/mailsignup"; + $post_elements=array('MODE'=>'CANOEMAIL_LOGIN', + 'LOOK'=>'CANOEMAILv2', + 'username'=>$user, + 'password'=>$pass, + 'login.x'=>rand(1,50), + 'login.y'=>rand(1,50) + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_file_contacts='http://www.canoemail.com/contacts/contacts_import_export.asp?action=export&app=Outlook_2000&NewContacts=true&ContactType=all'; + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $$contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.canoemail.com/logout.asp?action=logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/care2.plg.php b/plugins/contact_importer/OpenInviter/plugins/care2.plg.php new file mode 100755 index 00000000..f825dbaa --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/care2.plg.php @@ -0,0 +1,188 @@ +<?php +$_pluginInfo=array( + 'name'=>'Care2', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Care2 account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://passport.care2.net/login.html?promoID=1', + 'requirement'=>'email', + 'allowed_domains'=>array('/(care2.com)/i'), + ); +/** + * Care2 Plugin + * + * Import user's contacts from Care2 account + * + * + * @author OpenInviter + * @version 1.0.2 + */ +class care2 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'nofollow', + 'login_post'=>'navbar-email', + 'url_home'=>'self.location.replace', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='care2'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.care2.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://passport.care2.net/login.html?promoID=1",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://passport.care2.net/login.html?promoID=1",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://passport.care2.net/login.html?promoID=1"; + $post_elements=array('promoID'=>1, + 'loginemail'=>$user, + 'password'=>$pass, + 'perm'=>'on', + 'login'=>'Log In' + ); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $res=$this->get('http://www.care2.com',true); + if ($this->checkResponse("url_home",$res)) + $this->updateDebugBuffer('url_home',"http://www.care2.com/mail.html",'GET'); + else + { + $this->updateDebugBuffer('url_home',"http://www.care2.com/mail.html",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_file_contacts='http://mail.care2.com/contacts/contacts_import_export.asp?action=export&app=Outlook_2007&NewContacts=true&ContactType=all'; + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[2])) + $contacts[$values[2]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[2])?$values[2]:false), + 'email_2'=>(!empty($values[3])?$values[3]:false), + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://mail.care2.com/s/care2/logout.asp",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/clevergo.plg.php b/plugins/contact_importer/OpenInviter/plugins/clevergo.plg.php new file mode 100755 index 00000000..f57b7e71 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/clevergo.plg.php @@ -0,0 +1,180 @@ +<?php +$_pluginInfo=array( + 'name'=>'Clevergo', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Clevergo account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.clevergo.com/index.php', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Doramail.com Plugin + * + * Imports user's contacts from Clevergo.com AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class clevergo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + + public $debug_array=array( + 'initial_get'=>'email_local', + 'login_post'=>'sid', + 'contacts_file'=>'Firstname' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='clevergo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.clevergo.com/index.php"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.clevergo.com/index.php?action=login"; + $post_elements=array('do'=>'login','email_local'=>$user,'email_domain'=>'clevergo.com','passwordMD5'=>md5($pass),'language'=>'english'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $sid=$this->getElementString($res,'email.php?sid=','"'); + $this->login_ok=$sid; + file_put_contents($this->getLogoutPath(),$sid); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $sid=$this->login_ok; + + $form_action="http://www.clevergo.com/organizer.addressbook.php?action=exportAddressbook&sid={$sid}"; + $post_elements=array('lineBreakChar'=>'lf','sepChar'=>'comma','quoteChar'=>'double'); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res);$teM=explode(PHP_EOL,$res);$arrayDescriptionFlag=explode(',',$teM[0]);print_R($arrayDescriptionFlag); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[9])) + $contacts[$values[9]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[9])?$values[9]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $sid=file_get_contents($this->getLogoutPath()); + $res=$this->get("http://www.clevergo.com/start.php?sid={$sid}&action=logout",true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/cyworld.plg.php b/plugins/contact_importer/OpenInviter/plugins/cyworld.plg.php new file mode 100755 index 00000000..10ce3986 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/cyworld.plg.php @@ -0,0 +1,212 @@ +<?php +/*Import Friends from Cyworld + * You can Post Messages using Cyworld system + */ +$_pluginInfo=array( + 'name'=>'Cyworld', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Cyworld account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://us.cyworld.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Cyworld Plugin + * + * Import user's contacts from Flixster and Post comments + * using Flixster's internal Posting system + * + * @author OpenInviter + * @version 1.0.0 + */ +class cyworld extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + + public $debug_array=array( + 'initial_get'=>'Cyworld', + 'login_post'=>'MyHompy_GSP', + 'url_home'=>'selected nobg', + 'get_friends'=>'imgbox', + 'url_send_message'=>'MemoContent', + 'send_message'=>'replace' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='cyworld'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://us.cyworld.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://us.cyworld.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://us.cyworld.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://us.cyworld.com/common/include/login_check_proc.php"; + $post_elements=array("txtEmail"=>$user, + "txtPassword"=>$pass, + "hidReturnURL"=>'/', + "c.x"=>rand(1,20), + "c.y"=>rand(1,20), + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $res=$this->get('http://us.cyworld.com/'); + if ($this->checkResponse("url_home",$res)) + $this->updateDebugBuffer('url_home',"http://us.cyworld.com/",'GET'); + else + { + $this->updateDebugBuffer('url_home',"http://us.cyworld.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//li[@class='selected nobg']";$data=$xpath->query($query); + foreach($data as $node) + $url_profile=$node->nextSibling->nextSibling->firstChild->getAttribute('href'); + $this->login_ok=$url_profile; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@id='imgbox']";$data=$xpath->query($query); + foreach($data as $node) + { + $name_array=explode("/",$node->childNodes->item(1)->getAttribute('href')); + $href=$node->childNodes->item(1)->getAttribute('href'); + if (!empty($name_array[3])) $contacts[$href]=!empty($name_array[3])?$name_array[3]:false; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message="{$href}/message/send_message"; + $res=$this->get($url_send_message); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://us.cyworld.com/main/memo_send_proc.php"; + $post_elements=$this->getHiddenElements($res);$post_elements['MemoContent']=$message['body']; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://us.cyworld.com/common/include/logout_proc.php"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/doramail.plg.php b/plugins/contact_importer/OpenInviter/plugins/doramail.plg.php new file mode 100755 index 00000000..eec0ba2d --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/doramail.plg.php @@ -0,0 +1,230 @@ +<?php +$_pluginInfo=array( + 'name'=>'Doramail', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Doramail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.doramail.com/scripts/common/index.main?signin=1&lang=us', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Doramail.com Plugin + * + * Imports user's contacts from Doramail.com AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class doramail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'show_frame', + 'login_post'=>'frame', + 'url_inbox'=>'mailbox', + 'url_adressbook'=>'scripts', + 'url_export'=>'cgi', + 'export_file'=>'csv', + 'contacts_file'=>'Name' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='doramail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.doramail.com/scripts/common/index.main?signin=1&lang=us"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.doramail.com/scripts/common/proxy.main"; + $post_elements=array('show_frame'=>'Enter', + 'action'=>'login', + 'domain'=>'doramail.com', + 'mail_language'=>'us', + 'longlogin'=>1, + 'login'=>$user, + 'password'=>$pass, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_frame_array=$this->getElementDOM($res,"//frame",'src'); + $res=$this->get($url_frame_array[1]); + if ($this->checkResponse("url_inbox",$res)) + $this->updateDebugBuffer('url_inbox',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('url_inbox',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_inbox='http://mymail.doramail.com/scripts/mail/mailbox.mail?'.$this->getElementString($res,'/scripts/mail/mailbox.mail?','"'); + $res=$this->get($url_inbox); + if ($this->checkResponse("url_adressbook",$res)) + $this->updateDebugBuffer('url_adressbook',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('url_adressbook',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_adressbook='http://mymail.doramail.com/scripts/addr/'.$this->getElementString($res,'/scripts/addr/','"'); + $this->login_ok=$url_adressbook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_export",$res)) + $this->updateDebugBuffer('url_export',$url,'GET'); + else + { + $this->updateDebugBuffer('url_export',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_export='http://mymail.doramail.com/scripts/addr/external.cgi?'.$this->getElementString($res,'http://mymail.doramail.com/scripts/addr/external.cgi?','"'); + $res=$this->get($url_export); + if ($this->checkResponse("export_file",$res)) + $this->updateDebugBuffer('export_file',$url,'GET'); + else + { + $this->updateDebugBuffer('export_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action=$url_export; + $post_elements=$this->getHiddenElements($res);$post_elements['format']='csv'; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://mymail.doramail.com/scripts/mail/Outblaze.mail?logout=1&.noframe=1&a=1&',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/eons.plg.php b/plugins/contact_importer/OpenInviter/plugins/eons.plg.php new file mode 100755 index 00000000..288c0296 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/eons.plg.php @@ -0,0 +1,198 @@ +<?php +/*Import Friends from eons + * You can Write Private Messages using Brazencareerist system + */ +$_pluginInfo=array( + 'name'=>'Eons', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Eons account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.eons.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Eons Plugin + * + * Import Friends from Eons + * You can Write Private Messages using Eons system + * + * @author OpenInviter + * @version 1.0.0 + */ +class eons extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'account[username]', + 'login_post'=>'com/logout', + 'url_home'=>'/members/friends/', + 'get_friends'=>'cont-image member-card', + 'send_message'=>'sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='eons'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + + $res=$this->get("http://www.eons.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.eons.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.eons.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://www.eons.com/login"; + $post_elements=array('resource'=>'http://www.eons.com/','account[username]'=>$user,'account[password]'=>$pass,'permanent'=>1,'commit'=>'Log in'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_home="http://www.eons.com/my_eons"; + $res=$this->get($url_home,true); + if ($this->checkResponse("url_home",$res)) + $this->updateDebugBuffer('url_home',$url_home,'GET'); + else + { + $this->updateDebugBuffer('url_home',$url_home,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends='http://www.eons.com/members/friends/'.$this->getElementString($res,'/members/friends/','"'); + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='cont-image member-card']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->childNodes->item(3)->childNodes->item(1)->nodeValue; + if (!empty($name)) $contacts[$name]=!empty($name)?$name:false; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $form_action="http://www.eons.com/messages/write"; + $post_elements=array('ref'=>"http://www.eons.com/members/profile/{$name}", + 'msg[recipient_name]'=>$name, + 'msg[subject]'=>$message['subject'], + 'msg[body]'=>$message['body'], + 'commit'=>'Send Message' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("https://www.eons.com/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/evite.plg.php b/plugins/contact_importer/OpenInviter/plugins/evite.plg.php new file mode 100755 index 00000000..cf95e68a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/evite.plg.php @@ -0,0 +1,136 @@ +<?php +$_pluginInfo=array( + 'name'=>'Evite', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from an Evite account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.evite.com/', + 'requirement'=>'user', + 'allowed_domains'=>array('/(evite.com)/i'), + ); +/** + * Evite Plugin + * + * Imports user's contacts from Evite's AddressBook + * + * @author OpenInviter + * @version 1.0.1 + */ +class evite extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'initial_get'=>'submitForm', + 'login_post'=>'Log out', + 'get_contacts'=>'abCheck' + ); + +/** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='evite'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.evite.com/loginRegForm"; + $post_elements=array('cmd'=>'login','submitForm'=>'true','redirect'=>'http://www.evite.com/pages/addrbook/contactList.jsp','emailLogin'=>$user,'passLogin'=>$pass,'rememberMe'=>'on'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://www.evite.com/pages/addrbook/contactList.jsp"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('get_contacts',$res)) + $this->updateDebugBuffer('get_contacts',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET'); + else + { + $this->updateDebugBuffer('get_contacts',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//td[@class='abCheck']";$data=$xpath->query($query);$name=""; + foreach ($data as $node) + { + if ($node->getAttribute('style')=='padding-left:0px;width:149px;') $name.=" ".trim($node->nodeValue); + if ($node->getAttribute('style')=='width:219px;') {$email=trim((string)$node->nodeValue);$contacts[$email]=array('first_name'=>$name,'email_1'=>$email);$name="";} + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url="http://www.evite.com/logout?linkTagger=header"; + $res = $this->get($logout_url,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/facebook.plg.php b/plugins/contact_importer/OpenInviter/plugins/facebook.plg.php new file mode 100755 index 00000000..81122228 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/facebook.plg.php @@ -0,0 +1,251 @@ +<?php +/*Import Friends from Facebook + * You can send message to your Friends Inbox + */ +$_pluginInfo=array( + 'name'=>'Facebook', + 'version'=>'1.2.1', + 'description'=>"Get the contacts from a Facebook account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://m.facebook.com/index.php', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * FaceBook Plugin + * + * Imports user's contacts from FaceBook and sends + * messages using FaceBook's internal system. + * + * @author OpenInviter + * @version 1.0.8 + */ +class facebook extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'pass', + 'login_post'=>'accesskey="2"', + 'url_friends'=>'&a&refid=5', + 'get_friends'=>'summary border_bottom', + 'update_status'=>'notice border_bottom', + 'url_message'=>'body', + 'send_message'=>'notice' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='facebook'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://m.facebook.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.facebook.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.facebook.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=str_replace("&","&",urldecode($this->getElementString($res,'action="','"'))); + $post_elements=array('email'=>$user,'pass'=>$pass,'login'=>'Login In'); + $res=$this->post($form_action,$post_elements,true,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends_array=$this->getElementDOM($res,"//a[@accesskey='2']",'href'); + $url_friends='http://m.facebook.com'.$url_friends_array[0]; + $res=$this->get($url_friends,true); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url_friends,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url_friends,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + preg_match("#\<\/a\> \&\#8226\; \<a href\=\"\/friends\.php\?(.+)\&\;a\&\;refid\=5#U",$res,$url_my_friends_array); + if (!empty($url_my_friends_array[1])) $url_my_friends="http://m.facebook.com/friends.php?{$url_my_friends_array[1]}&a&refid=5"; + else $url_my_friends=false; + $this->login_ok=$url_my_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',"{$url}",'GET'); + else + { + $this->updateDebugBuffer('get_friends',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $nextPage=true;$friends=10;$page=1;$contacts=array(); + while($nextPage) + { + $nextPage=false; + if (preg_match_all("#\<td\>\<a href\=\"\/profile\.php(.+)\>(.+)\<\/a\>#U",$res,$names)) + if (!empty($names[2])) + if (preg_match_all("#\<small\>\<a href\=\"\/inbox\/(.+)\"\>#U",$res,$hrefs)) + { + if (!empty($hrefs[1][0])) unset($hrefs[1][0]); + foreach($hrefs[1] as $key=>$href) + if (!empty($names[2][($key-1)])) + if (!isset($contacts["/inbox".$href])) { $contacts["/inbox".$href]=htmlspecialchars($names[2][($key-1)]); $nextPage=true; } + } + //get the next page + if (!empty($nextPage)) + if (preg_match("#{$page}\ \;\<a href\=\"\/friends\.php\?(.+)\&\;a\&\;f={$friends}\&\;refid\=5\"\>#U",$res,$matches)) + { $nextPage="http://m.facebook.com/friends.php?{$matches[1]}&a&f={$friends}&refid=5";$res=$this->get($nextPage,true);$friends+=10;$page++; } + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $res=$this->get('http://m.facebook.com',true); + if (preg_match("#\/a\/home\.php\?r(.+)\"#U",$res,$form_action_array)) + $form_action='http://m.facebook.com'.str_replace('&','&',$form_action_array[0]); + else + { + $this->updateDebugBuffer('url_friends',"http://m.facebook.com",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $post_elements=$this->getHiddenElements($res);$post_elements['status']=$message['body'];$post_elements['update']=$this->getElementString($res,'name="update" value="','"'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("update_status",$res)) + $this->updateDebugBuffer('update_status',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('update_status',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $countMessages=0; + foreach ($contacts as $href=>$name) + { + $countMessages++; + $formatedHref='http://m.facebook.com'.str_replace('&','&',$href); + $res=$this->get($formatedHref,true); + if ($this->checkResponse("url_message",$res)) + $this->updateDebugBuffer('url_message',$formatedHref,'GET'); + else + { + $this->updateDebugBuffer('url_message',$formatedHref,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action_array=$this->getElementDOM($res,"//form[@method='post']","action"); + $form_action='http://m.facebook.com'.str_replace('&','&',$form_action_array[0]); + $post_elements=array('subject'=>$message['subject'], + 'body'=>$message['body'], + 'send'=>$this->getElementString($res,'name="send" value="','"'), + 'post_form_id'=>$this->getElementString($res,'name="post_form_id" value="','"'), + 'compose'=>1, + 'ids'=>$this->getElementString($res,'name="ids" value="','"'), + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://m.facebook.com",true); + if (!empty($res)) + { + $url_logout="http://m.facebook.com/logout.php".str_replace('&','&',$this->getElementString($res,'/logout.php','"')); + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/faces.plg.php b/plugins/contact_importer/OpenInviter/plugins/faces.plg.php new file mode 100755 index 00000000..23939fc2 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/faces.plg.php @@ -0,0 +1,173 @@ +<?php +/*Import Friends from Faces + * You can Write Private Messages using Faces system + */ +$_pluginInfo=array( + 'name'=>'Faces', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Faces account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.faces.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Faces Plugin + * + * Import Friends from Faces + * You can Write Private Messages using Faces system + * + * @author OpenInviter + * @version 1.0.0 + */ +class faces extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'loginName', + 'login_post'=>'logout', + 'get_friends'=>'name', + 'send_message'=>'Inbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='faces'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.faces.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.faces.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.faces.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.faces.com/login"; + $post_elements=array('loginName'=>$user, + 'password'=>$pass, + 'action'=>'log in' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.faces.com/friends'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,"//a[@class='name']"); + if (!empty($names_array)) + foreach($names_array as $key=>$value) $contacts[$value]=$value; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $form_action="http://www.faces.com/mailbox/compose"; + $post_elements=array('scoop'=>'scoop', + 'subject'=>$message['subject'], + 'message'=>$message['body'], + 'send'=>'Send' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.faces.com/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/famiva.plg.php b/plugins/contact_importer/OpenInviter/plugins/famiva.plg.php new file mode 100755 index 00000000..f54d0910 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/famiva.plg.php @@ -0,0 +1,150 @@ +<?php +/*Import Friends from Famiva + * You can Write Private Messages using Famiva system + */ +$_pluginInfo=array( + 'name'=>'Famiva', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Famiva account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.famiva.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Famiva Plugin + * + * Import Friends from Famiva + * You can Write Private Messages using Famiva system + * + * @author OpenInviter + * @version 1.0.0 + */ +class famiva extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'member[email]', + 'login_post'=>'logout', + 'get_friends'=>'data', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='famiva'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.famiva.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.famiva.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.famiva.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://famiva.com/login/login"; + $post_elements=array('member[email]'=>$user, + 'member[password]'=>$pass, + 'remember_me'=>true, + 'commit'=>'Login' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://famiva.com/members/explore'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + if (strpos($node->getAttribute('href'),'profiles/view')!=false) + { + $name=$node->nodeValue; + $email=$node->parentNode->nextSibling->nextSibling->nodeValue; + if (!empty($email)) $contacts[$email]=!empty($name)?$name:false; + } + if (isset($contacts[$this->service_user])) unset($contacts[$this->service_user]); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $contacts; + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.famiva.com/login/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/fastmail.plg.php b/plugins/contact_importer/OpenInviter/plugins/fastmail.plg.php new file mode 100755 index 00000000..738a8dc1 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/fastmail.plg.php @@ -0,0 +1,253 @@ +<?php +$_pluginInfo=array( + 'name'=>'FastMail', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a FastMail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.fastmail.fm', + 'requirement'=>'email', + 'allowed_domains'=>array('/(fastmail.fm)/i'), + ); +/** + * FastMail Plugin + * + * Imports user's contacts from FastMail's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class fastmail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'FLN-LoginMode', + 'post_login'=>'redirected', + 'url_webinterface'=>'kbshortcut', + 'url_get_webinterface'=>'kbshortcut', + 'contacts_page'=>'MC-From', + 'contacts_file'=>'Title', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='fastmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.fastmail.fm/"); + + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.fastmail.fm/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.fastmail.fm/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=$this->getElementString($res,'action="','"'); + $post_elements=array('MLS'=>'=LN-*', + 'FLN-LoginMode'=>0, + 'FLN-UserName'=>$user, + 'FLN-Password'=>$pass, + 'MSignal_LN-AU*'=>'Login', + 'FLN-Security'=>0, + 'FLN-ScreenSize'=>3, + 'FLN-SessionTime'=>1800, + 'FLN-NoCache'=>'on' + + ); + $res=$this->post($form_action,$post_elements,TRUE); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + if (strpos($res,'ChooseWeb-*')!==false) + { + $form_action=$this->getElementString($res,'post" action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['FChooseWeb-WebInterface']=2; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('url_webinterface',$res)) + $this->updateDebugBuffer('url_webinterface',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('url_webinterface',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + else + { + $url_redirect=$this->getElementString($res,'href="','"'); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('url_get_webinterface',$res)) + $this->updateDebugBuffer('url_get_webinterface',"{$url_redirect}","GET",'GET'); + else + { + $this->updateDebugBuffer('url_get_webinterface',"{$url_redirect}","GET",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + + $url_adress_book=$this->getElementDOM($res,"//a[@kbshortcut='b']",'href'); + $url_adress="http://www.fastmail.fm".$url_adress_book[0]; + file_put_contents($this->getLogoutPath(),$url_adress); + $this->login_ok=$url_adress; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + + $form_action=$this->getElementString($res,'action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['MSignal_UA-*U-1']='Upload/Download'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('contacts_page',$res)) + $this->updateDebugBuffer('contacts_page',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_page',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=array(); + $form_action=$this->getElementString($res,'action="','"'); + $post_elements['nojs']=0; + $post_elements['_charset_']='ISO-8859-1'; + $post_elements['MLS']='UA-*'; + $post_elements['MSS']='!AD-*'; + $post_elements['SAD-AL-DR']=0; + $post_elements['FUA-DownloadFormat']='OL'; + $post_elements['FUA-Group']=0; + $post_elements['MSignal_UA-Download*']=''; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse('contacts_file',$res)) + $this->updateDebugBuffer('contacts_file',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_file',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array();$descriptionArray=array(); + foreach ($temp as $values) + { + if (!empty($values[34])) + $contacts[$values[34]]=array('first_name'=>(!empty($values[1])?$values[1]:false), + 'middle_name'=>false, + 'last_name'=>(!empty($values[2])?$values[2]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[34])?$values[34]:false), + 'email_2'=>(!empty($values[35])?$values[35]:false), + 'email_3'=>(!empty($values[36])?$values[36]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[30])?$values[30]:false), + 'phone_home'=>(!empty($values[28])?$values[28]:false), + 'pager'=>(!empty($values[32])?$values[32]:false), + 'address_home'=>false, + 'address_city'=>(!empty($values[15])?$values[15]:false), + 'address_state'=>(!empty($values[16])?$values[16]:false), + 'address_country'=>(!empty($values[18])?$values[18]:false), + 'postcode_home'=>(!empty($values[17])?$values[17]:false), + 'company_work'=>(!empty($values[4])?$values[4]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[9])?$values[9]:false), + 'address_work_country'=>(!empty($values[12])?$values[12]:false), + 'address_work_state'=>(!empty($values[10])?$values[10]:false), + 'address_work_postcode'=>(!empty($values[11])?$values[11]:false), + 'fax_work'=>false, + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[38])?$values[38]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + //go to url adress book url in order to make the logout + $res=$this->get($url,true); + $form_action=$this->getElementString($res,'action="','"'); + $post_elements=$this->getHiddenElements($res); + $post_elements['MSignal_AD-LGO*C-1.N-1']='Logout'; + + //get the post elements and make de logout + $res=$this->post($form_action,$post_elements,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/fdcareer.plg.php b/plugins/contact_importer/OpenInviter/plugins/fdcareer.plg.php new file mode 100755 index 00000000..f52f5649 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/fdcareer.plg.php @@ -0,0 +1,189 @@ +<?php +/*Import Friends from fdcareer + * You can Write Private Messages using fdcareer system + */ +$_pluginInfo=array( + 'name'=>'Fdcareer', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Fdcareer account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.fdcareer.com/user/login', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * fdcareer Plugin + * + * Import Friends from fdcareer + * You can Write Private Messages using fdcareer system + * + * @author OpenInviter + * @version 1.0.0 + */ +class fdcareer extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'md5password', + 'login_post'=>'logout', + 'get_friends'=>'Send a message', + 'url_send_message'=>'recipient_id', + 'send_message'=>'Inbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='fdcareer'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.fdcareer.com/user/login",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.fdcareer.com/user/do_login"; + $post_elements=array('email'=>$user, + 'md5password'=>md5($pass), + 'timezone_offset'=>-120, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.fdcareer.com/my/friends'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $names_array=$this->getElementDOM($res,"//a [@style='margin-bottom:5px;display:block']"); + $href_array=$this->getElementDOM($res,"//a [@title='Send a message']",'href'); + foreach($href_array as $key=>$value) + if (!empty($value)) $contacts[$value]=$names_array[$key]; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $res=$this->get($href); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$href,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$href,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.fdcareer.com/my/inbox/send/0"; + $post_elements['recipient_id']=$this->getElementString($res,"name='recipient_id' id='recipient_id' value='","'");$post_elements['recipients']=$name;$post_elements['subject']=$message['subject'];$post_elements['body']=$message['body']; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.fdcareer.com/user/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/flickr.plg.php b/plugins/contact_importer/OpenInviter/plugins/flickr.plg.php new file mode 100755 index 00000000..9ba357fd --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/flickr.plg.php @@ -0,0 +1,210 @@ +<?php +/*Import Friends from Flickr.com + * You can send private message using Flickr system to your Friends + */ +$_pluginInfo=array( + 'name'=>'Flickr', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from a Flickr account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.flickr.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Flickr Plugin + * + * Imports user's contacts from Flickr and send messages + * using Flickr's internal system + * + * @author OpenInviter + * @version 1.0.2 + */ +class flickr extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login.yahoo', + 'login_post'=>'window.location.replace(', + 'redirect_cookie'=>'magic_cookie', + 'frinds_page'=>'Who', + 'send_message_url'=>'magic_cookie', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='flickr'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.flickr.com/signin/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.flickr.com/signin/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.flickr.com/signin/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://login.yahoo.com/config/login?"; + $post_elements=$this->getHiddenElements($res);$post_elements["save"]="Sign In";$post_elements['login']=$user;$post_elements['passwd']=$pass; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=$this->getElementString($res,'window.location.replace("','"'); + $res=$this->get($url_redirect,true); + if ($this->checkResponse("redirect_cookie",$res)) + $this->updateDebugBuffer('redirect_cookie',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('redirect_cookie',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends="http://www.flickr.com/people/".$this->getElementString("$res",'<span><a href="/photos/','"')."contacts/?see=friends"; + + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + + if ($this->checkResponse("frinds_page",$res)) + $this->updateDebugBuffer('frinds_page',$url,'GET'); + else + { + $this->updateDebugBuffer('frinds_page',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@rel='contact']";$data=$xpath->query($query); + foreach($data as $node) + { + if (strpos($node->getAttribute('title'),'photos')!==false) + { + $name=$node->nodeValue; + $id=str_replace('/','',str_replace('/photos/','',(string)$node->getAttribute('href'))); + if (!empty($name)) $contacts[$id]=$name; + } + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $url_send_message="http://www.flickr.com/messages_write.gne?to={$id}"; + $res=$this->get($url_send_message); + if ($this->checkResponse("send_message_url",$res)) + $this->updateDebugBuffer('send_message_url',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('send_message_url',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://www.flickr.com/messages_write.gne"; + $post_elements=array("magic_cookie"=>$this->getElementString($res,'name="magic_cookie" value="','"'), + "to"=>$this->getElementString($res,'name="to" value="','"'), + "to_nsid"=>$this->getElementString($res,'name="to_nsid" value="','"'), + "reply"=>"", + "done"=>1, + "subject"=>$message['subject'], + "message"=>$message['body'] + ); + $res=$this->post($form_action,$post_elements); + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.flickr.com/"); + $logout_url="http://www.flickr.com/logout.gne?magic_cookie=".$this->getElementString($res,'/logout.gne?magic_cookie=','"'); + $res=$this->get($logout_url); + $res=$this->get("http://login.yahoo.com/config/login?logout=1&.intl=us&.done=http://us.yahoo.com"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/flingr.plg.php b/plugins/contact_importer/OpenInviter/plugins/flingr.plg.php new file mode 100755 index 00000000..ca0f056c --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/flingr.plg.php @@ -0,0 +1,184 @@ +<?php +/*Import Friends from Flingr + * You can Write Private Messages using Flingr system + */ +$_pluginInfo=array( + 'name'=>'Flingr', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Flingr account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.flingr.com/index.php', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Flingr Plugin + * + * Import Friends from Flingr + * You can Write Private Messages using Flingr system + * + * @author OpenInviter + * @version 1.0.0 + */ +class flingr extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'email', + 'login_post'=>'logout', + 'get_friends'=>'friend-actions', + 'send_message'=>'UserID' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='flingr'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.flingr.com/index.php",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.flingr.com/index.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.flingr.com/index.php",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.flingr.com/login.php"; + $post_elements=array('email'=>$user, + 'password'=>$pass, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.flingr.com/friends/action/viewall/UserID/'.$this->getElementString($res,'http://www.flingr.com/friends/action/viewall/UserID/','/').'/'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//span[@class='friend-actions']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=trim((string)$node->childNodes->item(0)->nodeValue); + $id=str_replace('/','',str_replace('http://www.flingr.com/friends/action/remove/UserID/','',(string)$node->childNodes->item(1)->childNodes->item(0)->getAttribute('href'))); + if (!empty($id)) $contacts[$id]=(!empty($name)?$name:false); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://www.flingr.com/messages/action/send/UserID/{$id}/"; + $post_elements=array('Title'=>$message['subject'], + 'editor'=>$message['body'], + 'submit'=>'Send Message' + ); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.flingr.com/login/action/logout/"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/flixster.plg.php b/plugins/contact_importer/OpenInviter/plugins/flixster.plg.php new file mode 100755 index 00000000..bd99e216 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/flixster.plg.php @@ -0,0 +1,207 @@ +<?php +/*Import Friends from Flixster + * You can Post Messages using Flixster system + */ +$_pluginInfo=array( + 'name'=>'Flixster', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a Flixster account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.flixster.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Flixster Plugin + * + * Import user's contacts from Flixster and Post comments + * using Flixster's internal Posting system + * + * @author OpenInviter + * @version 1.0.4 + */ +class flixster extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'userauthAction', + 'login_post'=>'TalkCommentPopupLink', + 'get_friends'=>'username', + 'url_friends'=>'addProfileComment=&friendsUserId', + 'send_message'=>'comment' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='flixster'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.flixster.com/friends"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.flixster.com/friends",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.flixster.com/friends",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.flixster.com/userAuth.do"; + $post_elements=array("userauthAction"=>"doLogin", + "redirectTarget"=>"/friends", + "userauthEmail"=>$user, + "userauthPassword"=>$pass, + "userauthRemember"=>"on", + "submit"=>"Login to Flixster >" + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friend=explode("@",$user); + $url_friends="http://www.flixster.com/user/{$url_friend[0]}/friends"; + + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@class='username']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=str_replace("...","",$node->nodeValue); + $id=$node->getAttribute('href'); + if (!empty($name)) $contacts[$id]=!empty($name)?$name:false; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $res=$this->get("http://www.flixster.com{$id}"); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',"http://www.flixster.com{$id}",'GET'); + else + { + $this->updateDebugBuffer('url_friends',"http://www.flixster.com{$id}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $user_id=$this->getElementString($res,'addProfileComment=&friendsUserId=','"'); + $form_action="http://www.flixster.com/talk.do "; + $post_elements=array( + 'talkAction'=>'addProfileComment', + 'talkAnchor'=>'comments', + 'friendsUserId'=>$user_id, + 'comment'=>$message['body'], + 'submit'=>'Send' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.flixster.com/userAuth.do?userauthAction=doLogout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/fm5.plg.php b/plugins/contact_importer/OpenInviter/plugins/fm5.plg.php new file mode 100755 index 00000000..3b4116ec --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/fm5.plg.php @@ -0,0 +1,186 @@ +<?php +$_pluginInfo=array( + 'name'=>'5Fm', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a 5fm.za.com account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.5fm.za.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * 5FM.za.com Plugin + * + * Imports user's contacts from 5FM.za.com AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class fm5 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'secretkey', + 'login_post'=>'webmail', + 'url_export'=>'export', + 'contacts_file'=>',' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='5fm'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.5fm.za.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.5fm.za.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.5fm.za.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://webmail.5fm.za.com/src/redirect.php"; + $post_elements=array('login_domain'=>'5fm.za.com', + 'login_username'=>$user, + 'secretkey'=>$pass, + 'login'=>'login' + ); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_adressbook='http://webmail.5fm.za.com/src/addressbook.php'; + $this->login_ok=$url_adressbook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_export",$res)) + $this->updateDebugBuffer('url_export',$url,'GET'); + else + { + $this->updateDebugBuffer('url_export',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://webmail.5fm.za.com/plugins/abook_import_export/address_book_export.php'; + $res=$this->post($form_action,array()); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,array()); + else + { + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,array()); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://webmail.5fm.za.com/src/signout.php',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/freemail.plg.php b/plugins/contact_importer/OpenInviter/plugins/freemail.plg.php new file mode 100755 index 00000000..68058ea5 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/freemail.plg.php @@ -0,0 +1,148 @@ +<?php +$_pluginInfo=array( + 'name'=>'Freemail', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a freemail.hu account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://freemail.hu/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(freemail.hu)/i'), + ); +/** + * Freemail.hu Plugin + * + * Imports user's contacts from Freemail.hu AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class freemail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'userwithoutdomain', + 'login_post'=>'auth=ok', + 'url_adressbook'=>'first', + ); + + /** + * Login function + * fr + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='freemail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://freemail.hu/levelezes/login.fm"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.doramail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $userStried=str_replace("@freemail.hu","",$user); + $form_action="http://belepes.t-online.hu/auth.html"; + $post_elements=array('.formId'=>'commands.PlusAuth', + 'backurl'=>'http://freemail.hu/levelezes/auth.fm?cmd=checkuser&page=levelezes', + 'cmd'=>'plusauth', + 'remoteform'=>1, + 'user'=>$user, + 'userwithoutdomain'=>$userStried, + 'pass'=>'anaare12' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_redirect=$this->getElementString($res,'url=','"');$url_adressbook=str_replace(array('levelezes/auth.fm?cmd=checkuser&page=levelezes&status=ok&auth=ok&','tid','email','freul_Id.hu'),array('cc/fsAddressBook.do?','ul_Tid','ul_Id','freemail.hu'),$url_redirect); + $this->login_ok=$url_adressbook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_adressbook",$res)) + $this->updateDebugBuffer('url_adressbook',$url,'GET'); + else + { + $this->updateDebugBuffer('url_adressbook',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//tr[@class='data']";$data=$xpath->query($query); + foreach($data as $node) + { + $names=trim(preg_replace('/[^(\x20-\x7F)]*/','',utf8_decode((string)$node->childNodes->item(2)->nodeValue))); + $emails=trim(preg_replace('/[^(\x20-\x7F)]*/','',(utf8_decode((string)$node->childNodes->item(4)->nodeValue)))); + if (!empty($emails)) $contacts[$emails]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$emails); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://freemail.hu/levelezes/main.fm?page=logout',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/friendfeed.plg.php b/plugins/contact_importer/OpenInviter/plugins/friendfeed.plg.php new file mode 100755 index 00000000..b6da0207 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/friendfeed.plg.php @@ -0,0 +1,191 @@ +<?php +/*Import Friends from Friendfeed + * You can POST message to your Friends + */ +$_pluginInfo=array( + 'name'=>'Friendfeed', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Friendfeed account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'https://friendfeed.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * FaceBook Plugin + * + * Imports user's contacts from FaceBook and sends + * messages using FaceBook's internal system. + * + * @author OpenInviter + * @version 1.0.0 + */ +class friendfeed extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'email', + 'login_post'=>'Photos', + 'friends'=>'class="picture medium"', + 'url_home'=>'share', + 'send_message'=>'sid=' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='friendfeed'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://friendfeed.com/account/login",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"https://friendfeed.com/account/login",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://friendfeed.com/account/login",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://friendfeed.com/account/login"; + $post_elements=$this->getHiddenElements($res); + $post_elements["email"]=$user;$post_elements["password"]=$pass; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends="https://friendfeed.com/friends"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("friends",$res)) + $this->updateDebugBuffer('friends',$url,'GET'); + else + { + $this->updateDebugBuffer('friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $contacts=$this->getElementDOM($res,"//img[@class='picture large']",'alt'); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $res=$this->get("http://friendfeed.com/filter/direct?dm={$name}",true); + if ($this->checkResponse('url_home',$res)) + $this->updateDebugBuffer('url_home',"http://friendfeed.com/",'GET'); + else + { + $this->updateDebugBuffer('url_home',"http://friendfeed.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://friendfeed.com/a/share"; + $post_elements=array('streams'=>$name, + 'direct_view'=>1, + 'title'=>$message['body'], + 'at'=>$this->getElementString($res,'name="at" value="','"'), + 'maybetweet'=>0, + '_nano'=>1 + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://friendfeed.com/account/logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/friendster.plg.php b/plugins/contact_importer/OpenInviter/plugins/friendster.plg.php new file mode 100755 index 00000000..1b97bfd9 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/friendster.plg.php @@ -0,0 +1,208 @@ +<?php +/*Import Friends from Friendster.com + * You can send private message using Friendster system to your Friends + */ +$_pluginInfo=array( + 'name'=>'Friendster', + 'version'=>'1.0.9', + 'description'=>"Get the contacts from a Friendster account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.friendster.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Friendster Plugin + * + * Import user's contacts from Friendster and send messages + * using Friendster's internal messaging system + * + * @author OpenInviter + * @version 1.0.8 + */ +class friendster extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'_submitted', + 'login_post'=>'dict:snWhosViewedMe', + 'contacts'=>'thumbnaildelete', + 'message_compose'=>'msg_type', + 'message_send'=>'noliststyle noindent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='friendster'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.friendster.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.friendster.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.friendster.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.friendster.com/login.php"; + $post_elements=array('tzoffset'=>1, + 'next'=>'/', + '_submitted'=>1, + 'email'=>$user, + 'password'=>$pass + ); + $res=$this->post($form_action,$post_elements,true); + + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends="http://www.friendster.com/friends.php"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $res=$this->get($url,true); + $contacts=array(); + $page_next=0; + $number_of_friends_array=explode("of ",$this->getElementString($res,'class="paginglinksmodule">','<')); + if (!empty($number_of_friends_array[1])) $total_friends=$number_of_friends_array[1]; + else $total_friends=0; + do + { + $page_next++; + + //go to url friends + if ($this->checkResponse('contacts',$res)) + $this->updateDebugBuffer('contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//span[@class='strong']";$data=$xpath->query($query); + foreach ($data as $node) + $contacts[str_replace("http://profiles.friendster.com/","",(string)$node->firstChild->getAttribute('href'))]=(string)$node->firstChild->nodeValue; + $url_next="{$url}?page={$page_next}"; + $res=$this->get($url_next,true); + } + while ($total_friends>count($contacts)+1); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach ($contacts as $id=>$name) + { + $countMessages++; + $res=$this->get("http://www.friendster.com/sendmessage.php?uid={$id}",true); + if ($this->checkResponse('message_compose',$res)) + $this->updateDebugBuffer('message_compose',"http://www.friendster.com/sendmessage.php?uid={$id}",'GET'); + else + { + $this->updateDebugBuffer('message_compose',"http://www.friendster.com/sendmessage.php?uid={$id}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.friendster.com/sendmessage.php"; + $post_elements=$this->getHiddenElements($res); + $post_elements['message']=$message['body']; + $post_elements['subject']=$message['subject']; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('message_send',$res)) + $this->updateDebugBuffer('message_send',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('message_send',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.friendster.com/logout.php",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/gawab.plg.php b/plugins/contact_importer/OpenInviter/plugins/gawab.plg.php new file mode 100755 index 00000000..0e73b76a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/gawab.plg.php @@ -0,0 +1,176 @@ +<?php +$_pluginInfo=array( + 'name'=>'Gawab', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Gawab account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.gawab.com/default.php', + 'requirement'=>'email', + 'allowed_domains'=>array('/(gawab.com)/i'), + ); +/** + * Gawab Plugin + * + * Imports user's contacts from Gawab's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class gawab extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'service', + 'post_login'=>'&_host', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='gawab'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.gawab.com/default.php",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.gawab.com/default.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.gawab.com/default.php",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $login_array=explode("@",$user); + $form_action="http://mail.gawab.com/login"; + $post_elements=array('service'=>'webmail', + 'username'=>$login_array[0], + 'domain'=>$login_array[1], + 'password'=>$pass + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $host=$this->getElementString($res,'&_host=',"'"); + $url_file_contacts="http://mail.gawab.com/{$host}/gwebmail?_module=contact&_action=export&format=outlook&_address=dbautu@gawab.com"; + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('file_contacts',$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[1])) + $contacts[$values[1]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>false, + 'last_name'=>false, + 'nickname'=>false, + 'email_1'=>(!empty($values[1])?$values[1]:false), + 'email_2'=>(!empty($values[2])?$values[2]:false), + 'email_3'=>(!empty($values[3])?$values[3]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[5])?$values[5]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>(!empty($values[6])?$values[6]:false), + 'address_home'=>(!empty($values[12])?$values[12]:false), + 'address_city'=>false, + 'address_state'=>false, + 'address_country'=>false, + 'postcode_home'=>false, + 'company_work'=>(!empty($values[7])?$values[7]:false), + 'address_work'=>(!empty($values[16])?$values[16]:false), + 'address_work_city'=>false, + 'address_work_country'=>false, + 'address_work_state'=>false, + 'address_work_postcode'=>false, + 'fax_work'=>(!empty($values[15])?$values[15]:false), + 'phone_work'=>(!empty($values[13])?$values[13]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.gawab.com/",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/gmail.plg.php b/plugins/contact_importer/OpenInviter/plugins/gmail.plg.php new file mode 100755 index 00000000..2e719566 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/gmail.plg.php @@ -0,0 +1,168 @@ +<?php +/*This plugin import Gmail contacts + *You can send normal email + */ +$_pluginInfo=array( + 'name'=>'GMail', + 'version'=>'1.4.7', + 'description'=>"Get the contacts from a GMail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://google.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + 'detected_domains'=>array('/(gmail.com)/i','/(googlemail.com)/i'), + ); +/** + * GMail Plugin + * + * Imports user's contacts from GMail's AddressBook + * + * @author OpenInviter + * @version 1.4.1 + */ +class gmail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + + public $debug_array=array( + 'login_post'=>'Auth=', + 'contact_xml'=>'xml' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='gmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $post_elements=array('accountType'=>'HOSTED_OR_GOOGLE','Email'=>$user,'Passwd'=>$pass,'service'=>'cp','source'=>'OpenInviter-OpenInviter-'.$this->base_version); + $res=$this->post("https://www.google.com/accounts/ClientLogin",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"https://www.google.com/accounts/ClientLogin",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"https://www.google.com/accounts/ClientLogin",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $auth=substr($res,strpos($res,'Auth=')+strlen('Auth=')); + + $this->login_ok=$auth; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if ($this->login_ok===false) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $auth=$this->login_ok; + $res=$this->get("http://www.google.com/m8/feeds/contacts/default/full?max-results=10000",true,false,true,false,array("Authorization"=>"GoogleLogin auth={$auth}")); + if ($this->checkResponse("contact_xml",$res)) + $this->updateDebugBuffer('contact_xml','http://www.google.com/m8/feeds/contacts/default/full?max-results=10000','GET'); + else + { + $this->updateDebugBuffer('contact_xml','http://www.google.com/m8/feeds/contacts/default/full?max-results=10000','GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//entry";$data=$xpath->query($query); + foreach ($data as $node) + { + $entry_nodes=$node->childNodes; + $tempArray=array(); + foreach($entry_nodes as $child) + { + $domNodesName=$child->nodeName; + switch($domNodesName) + { + case 'title' : { $tempArray['first_name']=$child->nodeValue; } break; + case 'organization': { $tempArray['organization']=$child->nodeValue; } break; + case 'email' : + { + if (strpos($child->getAttribute('rel'),'home')!==false) + $tempArray['email_1']=$child->getAttribute('address'); + elseif(strpos($child->getAttribute('rel'),'work')!=false) + $tempArray['email_2']=$child->getAttribute('address'); + elseif(strpos($child->getAttribute('rel'),'other')!==false) + $tempArray['email_3']=$child->getAttribute('address'); + } break; + case 'phonenumber' : + { + if (strpos($child->getAttribute('rel'),'mobile')!==false) + $tempArray['phone_mobile']=$child->nodeValue; + elseif(strpos($child->getAttribute('rel'),'home')!==false) + $tempArray['phone_home']=$child->nodeValue; + elseif(strpos($child->getAttribute('rel'),'work_fax')!==false) + $tempArray['fax_work']=$child->nodeValue; + elseif(strpos($child->getAttribute('rel'),'pager')!=false) + $tempArray['pager']=$child->nodeValue; + } break; + case 'postaladdress' : + { + if (strpos($child->getAttribute('rel'),'home')!==false) + $tempArray['address_home']=$child->nodeValue; + elseif(strpos($child->getAttribute('rel'),'work')!==false) + $tempArray['address_work']=$child->nodeValue; + } break; + } + } + if (!empty($tempArray['email_1']))$contacts[$tempArray['email_1']]=$tempArray; + if(!empty($tempArray['email_2'])) $contacts[$tempArray['email_2']]=$tempArray; + if(!empty($tempArray['email_3'])) $contacts[$tempArray['email_3']]=$tempArray; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/gmx_net.plg.php b/plugins/contact_importer/OpenInviter/plugins/gmx_net.plg.php new file mode 100755 index 00000000..a08dc3c7 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/gmx_net.plg.php @@ -0,0 +1,202 @@ +<?php +/*This plugin import GMX.net contacts + *You can send normal email + */ +$_pluginInfo=array( + 'name'=>'GMX.net', + 'version'=>'1.0.9', + 'description'=>"Get the contacts from a GMX.net account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.gmx.net', + 'requirement'=>'email', + 'allowed_domains'=>array('/(gmx.de)/i','/(gmx.at)/i','/(gmx.ch)/i','/(gmx.net)/i'), + ); +/** + * GMX.net Plugin + * + * Imports user's contacts from GMX.net's AddressBook + * + * @author OpenInviter + * @version 1.0.4 + */ +class gmx_net extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'uinguserid', + 'login'=>'Adressbuch', + 'export_file'=>'b_export', + 'contacts_file'=>'","' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='gmx_net'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.gmx.net/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('file_contacts',"http://www.gmx.net/",'GET'); + else + { + $this->updateDebugBuffer('file_contacts',"http://www.gmx.net/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://service.gmx.net/de/cgi/login"; + $post_elements=array('AREA'=>1, + 'EXT'=>'redirect', + 'EXT2'=>'', + 'uinguserid'=>$this->getElementString($res,'name="uinguserid" value="','"'), + 'id'=>$user, + 'p'=>$pass, + 'dlevel'=>'c', + 'browsersupported'=>'true', + 'jsenabled'=>'false' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login",$res)) + $this->updateDebugBuffer('login',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_adress=str_replace("site=0","site=importexport","http://service.gmx.net/de/cgi/addrbk.fcgi?CUSTOMERNO=".html_entity_decode($this->getElementString($res,'http://service.gmx.net/de/cgi/addrbk.fcgi?CUSTOMERNO=','"'))); + #echo $url_adress; + $this->login_ok=$url_adress; + file_put_contents($this->getLogoutPath(),$url_adress); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("export_file",$res)) + $this->updateDebugBuffer('export_file',$url,'GET'); + else + { + $this->updateDebugBuffer('export_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://service.gmx.net/de/cgi/addrbk.fcgi"; + $post_elements=$this->getHiddenElements($res);$post_elements['dataformat']='o2002';$post_elements['language']='english';$post_elements['b_export']='Export starten'; + $res=$this->post($form_action,$post_elements); + + if ($this->checkResponse("contacts_file",$res)){ + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,$post_elements); + }else{ + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + + foreach ($temp as $values) + { + if (!empty($values[29])) + $contacts[$values[29]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[29])?$values[29]:false), + 'email_2'=>(!empty($values[30])?$values[30]:false), + 'email_3'=>(!empty($values[31])?$values[31]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + $res=$this->get($url,true); + $logout_url="https://service.gmx.net/de/cgi/nph-logout?CUSTOMERNO=".$this->getElementString($res,"https://service.gmx.net/de/cgi/nph-logout?CUSTOMERNO=",'"'); + $res=$this->get($logout_url,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/graffiti.plg.php b/plugins/contact_importer/OpenInviter/plugins/graffiti.plg.php new file mode 100755 index 00000000..f12f3eb2 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/graffiti.plg.php @@ -0,0 +1,141 @@ +<?php +$_pluginInfo=array( + 'name'=>'Grafitti', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Graffiti account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.graffiti.net/scripts/common/index.main?signin=1&lang=us', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Bordermail Plugin + * + * Imports user's contacts from Bordermail AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class graffiti extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'frontpage', + 'url_contacts'=>'input' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='graffiti'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.graffiti.net/scripts/common/index.main?signin=1&lang=us"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.graffiti.net/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.graffiti.net/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.graffiti.net/scripts/common/proxy.main"; + $post_elements=array('domain'=>'graffiti.net','show_frame'=>'Enter','login'=>$user,'password'=>$pass,'v'=>$this->getElementString($res,'name="v" value="','"'),'u'=>$this->getElementString($res,'name="u" value="','"')); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://mymail.graffiti.net/scripts/addr/addressbook.cgi?showaddressbook=1"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//input";$data=$xpath->query($query); + foreach ($data as $node) + { + $nodeValue=$node->getAttribute('value');$email=$this->getElementString($nodeValue,'<','>');$name=$this->getElementString($nodeValue,'to_"','"'); + if (!empty($email)) $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://mymail.graffiti.net/scripts/mail/Outblaze.mail?logout=1&.noframe=1&a=1&",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/hi5.plg.php b/plugins/contact_importer/OpenInviter/plugins/hi5.plg.php new file mode 100755 index 00000000..78e51748 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/hi5.plg.php @@ -0,0 +1,206 @@ +<?php +$_pluginInfo=array( + 'name'=>'Hi5', + 'version'=>'1.1.4', + 'description'=>"Get the contacts from a Hi5 account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.hi5.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Hi5 Plugin + * + * Imports user's contacts from Hi5 and sends messages + * using Hi5's internal messaging system. + * + * @author OpenInviter + * @version 1.0.4 + */ +class hi5 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=50; + + public $debug_array=array( + 'initial_get'=>'getAge', + 'login_post'=>'friends', + 'url_friends'=>'friend-name', + 'url_message'=>'toIds', + 'send_message'=>'reqs' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='hi5'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.hi5.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.hi5.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.hi5.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://www.hi5.com/friend/login.do"; + $post_elements=array( + 'email'=>$user, + 'password'=>$pass, + 'remember'=>'on' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends="http://www.hi5.com/friend/viewFriends.do?abredirect=true"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + $contacts=array();$mail_contacts=array();$url_next=false; + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $nr_of_friends=(int)$this->getElementString($res,'id="pagination-number">','<');$page=20; + do + { + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='friend-name']";$data=$xpath->query($query);$id=false; + foreach ($data as $node) + { + $name=$node->childNodes->item(1)->nodeValue;$href=$node->childNodes->item(1)->getAttribute('href');$id=$this->getElementString($href,'p','-'); + if (!empty($id)) $contacts[$id]=!empty($name)?$name:false; + } + $url_next_array=$this->getElementDOM($res,"//a[@class='link_pagination_arrow']",'href'); + if (!empty($url_next_array[0])) + {$url_next=$this->getElementString($url_next_array[0],'/','offset=')."offset={$page}";$page+=20;$res=$this->get("http://hi5.com/{$url_next}",true);} + else $id=false; + } + while($id); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $url_send_message="http://hi5.com/friend/mail/displayComposeMail.do?toIds={$id}"; + $res=$this->get($url_send_message); + if ($this->checkResponse("url_message",$res)) + $this->updateDebugBuffer('url_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://hi5.com/friend/mail/sendMail.do"; + $post_elements=array('toIds'=>$this->getElementString($res,"idToName['","'"), + 'subject'=>$message['subject'], + 'method'=>'send', + 'body'=>$message['body'], + 'timestamp'=>$this->getElementString($res,'name="timestamp" value="','"'), + 'mailOp'=>'', + 'senderId'=>'', + 'msgId'=>'', + 'submitSend'=>'Send Message' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',$url_send_message,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',$url_send_message,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://hi5.com/friend/logoff.do",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/hotmail.plg.php b/plugins/contact_importer/OpenInviter/plugins/hotmail.plg.php new file mode 100755 index 00000000..983cc1e5 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/hotmail.plg.php @@ -0,0 +1,224 @@ +<?php +$_pluginInfo=array( + 'name'=>'Live/Hotmail', + 'version'=>'1.6.2', + 'description'=>"Get the contacts from a Windows Live/Hotmail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://login.live.com/login.srf?id=2', + 'requirement'=>'email', + 'allowed_domains'=>array('/(hotmail)/i','/(live)/i','/(msn)/i','/(chaishop)/i'), + ); +/** + * Live/Hotmail Plugin + * + * Imports user's contacts from Windows Live's AddressBook + * + * @author OpenInviter + * @version 1.5.8 + */ +class hotmail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'LoginOptions', + 'login_post'=>'location.replace', + 'first_redirect'=>'self.location.href', + 'url_inbox'=>'peopleUrlDomain', + 'message_at_login'=>'peopleUrlDomain', + 'url_sent_to'=>'ContactList.aspx', + 'get_contacts'=>'\x26\x2364\x3', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + function login($user,$pass) + { + $this->resetDebugger(); + $this->service='hotmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://login.live.com/login.srf?id=2",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://login.live.com/login.srf?id=2",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://login.live.com/login.srf?id=2",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + if (strlen($pass) > 16) $pass=substr($pass, 0, 16); + $post_action=$this->getElementString($res,'method="POST" target="_top" action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements["LoginOptions"]=3;$post_elements["login"]=$user;$post_elements["passwd"]=$pass; + $res=$this->post($post_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$post_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$post_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=$this->getElementString($res,'.location.replace("','"'); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('first_redirect',$res)) + $this->updateDebugBuffer('first_redirect',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('first_redirect',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + if(strpos($res,"self.location.href = '")!==false) + { + $url_redirect=urldecode(str_replace('\x', '%',$this->getElementString($res,"self.location.href = '","'"))); + $base_url="http://".$this->getElementString($url_redirect,'http://','mail/'); + $res=$this->get($url_redirect,true); + } + + if (strpos($res,'MessageAtLoginForm')!==false) + { + $form_action=$base_url.'mail/'.html_entity_decode($this->getElementString($res,'method="post" action="','"')); + $post_elements=$this->getHiddenElements($res);$post_elements['TakeMeToInbox']='Continue'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("message_at_login",$res)) + $this->updateDebugBuffer('message_at_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('message_at_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + else + { + if ($this->checkResponse('url_inbox',$res)) + $this->updateDebugBuffer('url_inbox',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('url_inbox',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + + $this->login_ok=$base_url; + file_put_contents($this->getLogoutPath(),$base_url); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $base_url=$this->login_ok; + $res=$this->get("{$base_url}mail/EditMessageLight.aspx?n="); + if ($this->checkResponse('url_sent_to',$res)) + $this->updateDebugBuffer('url_sent_to',"{$base_url}mail/EditMessageLight.aspx?n=",'GET'); + else + { + $this->updateDebugBuffer('url_sent_to',"{$base_url}mail/EditMessageLight.aspx?n=",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $urlContacts="{$base_url}mail/ContactList.aspx".$this->getElementString($res,'ContactList.aspx','"'); + $res=$this->get($urlContacts); + if ($this->checkResponse('get_contacts',$res)) + $this->updateDebugBuffer('get_contacts',"{$urlContacts}",'GET'); + else + { + $this->updateDebugBuffer('get_contacts',"{$urlContacts}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $bulkStringArray=explode("['",$res);unset($bulkStringArray[0]);unset($bulkStringArray[count($bulkStringArray)]); + foreach($bulkStringArray as $stringValue) + { + $stringValue=str_replace(array("']],","'"),'',$stringValue); + if (strpos($stringValue,'0,0,0,')!==false) + { + $tempStringArray=explode(',',$stringValue); + if (!empty($tempStringArray[2])) $name=html_entity_decode(urldecode(str_replace('\x', '%', $tempStringArray[2])),ENT_QUOTES, "UTF-8"); + } + else + { + $emailsArray=array();$emailsArray=explode('\x26\x2364\x3b',$stringValue); + if (count($emailsArray)>0) + { + //get all emails + $bulkEmails=explode(',',$stringValue); + if (!empty($bulkEmails)) foreach($bulkEmails as $valueEmail) + { $email=html_entity_decode(urldecode(str_replace('\x', '%', $valueEmail))); if(!empty($email)) { $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email);$email=false; } } + $name=false; + } + } + } + if (!empty($contacts[$this->service_user])) unset($contacts[$this->service_user]); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + $url_logout=$url."mail/logout.aspx"; + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/hushmail.plg.php b/plugins/contact_importer/OpenInviter/plugins/hushmail.plg.php new file mode 100755 index 00000000..233de39e --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/hushmail.plg.php @@ -0,0 +1,152 @@ +<?php +$_pluginInfo=array( + 'name'=>'Hushmail', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from an Hushmail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'https://m.hush.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Hushmail Plugin + * + * Imports user's contacts from Hushmail's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class hushmail extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'initial_get'=>'passphrase', + 'login_post'=>'3Dmobile', + 'get_contacts'=>'compose_from', + 'url_contacts'=>'listItem' + ); + +/** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='hushmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("https://m.hush.com/",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"https://m.hush.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://m.hush.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='https://m.hush.com'.$this->getElementString($res,'action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['user']=$user;$post_elements['passphrase']=$pass; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_compose="https://m.hush.com/m/{$user}@hushmail.com/compose?next=%3Fskin%3Dmobile%26save_skin%3D1"; + $this->login_ok=$url_compose; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('get_contacts',$res)) + $this->updateDebugBuffer('get_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('get_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://m.hush.com".$this->getElementString($res,'action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['compose_from']="{$this->service_user}@hushmail.com";$post_elements['compose_encrypt']='on';$post_elements['compose_sign']='on';$post_elements['compose_save']='on';$post_elements['action']='Add contact (to)'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('url_contacts',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $contacts=array(); + $contacts_string_array=$this->getElementDOM($res,"//input[@type='checkbox']",'value'); + foreach($contacts_string_array as $temp) + { + $temp=str_replace('>','',str_replace('<','',str_replace('"','',urldecode($temp)))); + $contacts_array_temp=explode(' ',$temp); + if (isset($contacts_array_temp[1])) $contacts[$contacts_array_temp[1]]=array('first_name'=>(isset($contacts_array_temp[0])?$contacts_array_temp[0]:false),'email_1'=>$contacts_array_temp[1]); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url="https://m.hush.com/authentication/caracuraa@hushmail.com/logout?skin=mobile&next_webapp_name=contacts_webapp&next_webapp_url_name=contacts"; + $res = $this->get($logout_url,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/hyves.plg.php b/plugins/contact_importer/OpenInviter/plugins/hyves.plg.php new file mode 100755 index 00000000..c57c6f16 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/hyves.plg.php @@ -0,0 +1,236 @@ +<?php +/*Import Friends from Hyves + * You can Post Messages using Hyves system + */ +$_pluginInfo=array( + 'name'=>'Hyves', + 'version'=>'1.1.5', + 'description'=>"Get the contacts from a Hyves account", + 'base_version'=>'1.8.1', + 'type'=>'social', + 'check_url'=>'http://www.hyves.nl/?l1=mo', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * http://hyves.net/ Plugin + * + * Import user's contacts from Hyves and send private messages + * using Hyves system + * + * @author OpenInviter + * @version 1.1.2 + */ +class hyves extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'accesskey="1"', + 'url_login'=>'auth_username', + 'login_post'=>'hyver', + 'url_profile'=>'listitem', + 'get_friends'=>'memberlistname', + 'url_friend'=>'accesskey="2"', + 'url_send_message'=>'postman', + 'send_message'=>'color: green;' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='hyves'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.hyves.nl/?l1=mo"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.hyves.nl/?l1=mo",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.hyves.nl/?l1=mo",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_login_array=$this->getElementDOM($res,"//a[@accesskey='1']",'href'); + $res=$this->get('http://www.hyves.nl'.$url_login_array[0],true); + if ($this->checkResponse("url_login",$res)) + $this->updateDebugBuffer('$url_login',"http://www.hyves.nl".$url_login_array[0],'GET'); + else + { + $this->updateDebugBuffer('$url_login',"http://www.hyves.nl".$url_login_array[0],'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.hyves.nl/'.html_entity_decode($this->getElementString($res,'form action="','"')); + $post_elements=$this->getHiddenElements($res);$post_elements['auth_username']=$user;$post_elements['auth_password']=$pass;$post_elements['login']='ok'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_logout='http://www.hyves.nl/?module=authentication&action=logoutMobile'.html_entity_decode($this->getElementString($res,"?module=authentication&action=logoutMobile",'"')); + $url_friends="http://www.hyves.nl/mini/hyver/{$user}/list/?&startpos=0"; + $this->login_ok=$url_friends; + file_put_contents($this->getLogoutPath(),$url_logout); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array();$hasContacts=true;$page=0; + while ($hasContacts) + { + $hasContacts=false; + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@class='memberlistname'][not(contains(@href,'".$this->service_user."'))]";$data=$xpath->query($query); + foreach($data as $node) + {$href=$node->getAttribute('href');$name=(string)$node->nodeValue;if (!empty($name)) $name=$name[0].$this->getElementString($name,$name[0],'(');if (!empty($href)) {$contacts[$href]=!empty($name)?utf8_decode($name):false;$hasContacts=true;}} + $page=$page+10; + $urlNext="http://www.hyves.nl/mini/hyver/{$this->service_user}/list/?&startpos={$page}"; + $res=$this->get($urlNext,true); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $res=$this->get($href,true); + if ($this->checkResponse("url_friend",$res)) + $this->updateDebugBuffer('url_friend',$href,'GET'); + else + { + $this->updateDebugBuffer('url_friend',$href,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_send_message_array=$this->getElementDOM($res,"//a[@accesskey='2']",'href'); + $url_send_message='http://www.hyves.nl'.urldecode($url_send_message_array[0]); + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://www.hyves.nl/?l1=mo&l2=mb&l3=hm&l4=sendi"; + $post_elements=array( + 'postman'=>'Message/send', + 'postman_secret'=>$this->getElementString($res,'postman_secret" value="','"'), + 'sitepositionurl'=>$this->getElementString($res,'name="sitepositionurl" value="','"'), + 'sendmessage_to'=>$this->getElementString($res,'sendmessage_to" value="','"'), + 'sendmessage_subject'=>$message['subject'], + 'sendmessage_body'=>$message['body'], + 'sendmessage_type'=>2, + 'bsend'=>'send' + ); + + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout=file_get_contents($this->getLogoutPath()); + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/inbox.plg.php b/plugins/contact_importer/OpenInviter/plugins/inbox.plg.php new file mode 100755 index 00000000..66964587 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/inbox.plg.php @@ -0,0 +1,175 @@ +<?php +$_pluginInfo=array( + 'name'=>'Inbox.com', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from an Inbox.com account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'https://www.inbox.com/xm/login.aspx', + 'requirement'=>'email', + 'allowed_domains'=>array('/(inbox.com)/i'), + ); +/** + * Inbox.com Plugin + * + * Imports user's contacts from Inbox.com's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class inbox extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'ACT', + 'post_login'=>'Location:', + 'inbox'=>'accesskey="8"', + 'contacts'=>'checkbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='inbox'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://www.inbox.com/xm/login.aspx"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"https://www.inbox.com/xm/login.aspx",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://www.inbox.com/xm/login.aspx",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="https://www.inbox.com/xm/login.aspx"; + $post_elements=array('ACT'=>'LGN', + 'login'=>$user, + 'pwd'=>$pass, + 'cmdLgn'=>'Sign In' + ); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $base_url="http://".$this->getElementString($this->getElementString($res,"Location: ",PHP_EOL),"http://",'?ACT'); + $url_redirect=trim(str_replace(" [following]","",$this->getElementString($res,"Location: ",PHP_EOL))); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('inbox',$res)) + $this->updateDebugBuffer('inbox',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('inbox',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $url_contacts_array=$this->getElementDOM($res,"//a[@accesskey='8']",'href'); + $url_contacts=array();$url_contacts=array($base_url,$url_contacts_array[0]); + $this->login_ok=$url_contacts; + file_put_contents($this->getLogoutPath(),$url_redirect); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + //go to url adressbook + $res=$this->get($url[0].$url[1],true); + + $form_action=$url[0]."default.aspx";$post_elements=$this->getHiddenElements($res);$post_elements['cmdADDR']="To: Addr"; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('contacts',$res)) + $this->updateDebugBuffer('contacts',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array();$page=1; + $total_nr_friends_array=explode("of ",$this->getElementString($res,'<td align="center">','<'));if (!empty($total_nr_friends_array[1])) $total_nr_friends=trim($total_nr_friends_array[1]);else $total_nr_friends=0;$friend_contor=0; + while($total_nr_friends>$friend_contor) + { + $contacts_temp=$this->getElementDOM($res,"//input[@type='checkbox']",'value'); + foreach($contacts_temp as $value) + { + $contacts_array=explode("<",$value); + if (!empty($contacts_array[1])) $contacts[str_replace(">","",$contacts_array[1])]=(!empty($contacts_array[0])?trim($contacts_array[0]):false); + else $contacts[$value]=$value; + $friend_contor++; + } + $page++;$res=$this->get("{$form_action}?ACT=CPAB&AF=1&CID=-1&PG={$page}"); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + $url_logout=str_replace('?ACT=INIT','default.aspx?ACT=LGO',$url); + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/india.plg.php b/plugins/contact_importer/OpenInviter/plugins/india.plg.php new file mode 100755 index 00000000..027081c9 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/india.plg.php @@ -0,0 +1,179 @@ +<?php +$_pluginInfo=array( + 'name'=>'India', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from an India account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://mail.india.com/scripts/common/index.main?signin=1&lang=us', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * India plugin + * + * Imports user's contacts from India AddressBook + * + * @author OpenInviter + * @version 1.0.1 + */ +class india extends OpenInviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'show_frame', + 'login_post'=>'ob=', + 'file_contacts'=>'Name' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='indiatimes'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res = $this->get("http://mail.india.com/scripts/common/index.main?signin=1&lang=us"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://mail.india.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://mail.india.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://mail.india.com/scripts/common/proxy.main"; + $post_elements=array('show_frame'=>'Enter', + 'action'=>'login', + 'domain'=>'india.com', + 'u'=>$this->getElementString($res,'name="u" value="','"'), + 'v'=>$this->getElementString($res,'name="v" value="','"'), + 'mail_language'=>'us', + 'login'=>$user, + 'password'=>$pass, + ); + + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_export="http://mymail.india.com/scripts/addr/external.cgi?.ob=a&gab=1"; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $form_action=$url; + $post_elements=array('showexport'=>'showexport','action'=>'export','login'=>"{$this->service_user}@india.com",'format'=>'csv'); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('file_contacts',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>(!empty($values[2])?$values[2]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>(!empty($values[12])?$values[12]:false), + 'email_3'=>(!empty($values[13])?$values[13]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[10])?$values[10]:false), + 'phone_home'=>(!empty($values[6])?$values[6]:false), + 'pager'=>(!empty($values[8])?$values[8]:false), + 'address_home'=>false, + 'address_city'=>(!empty($values[28])?$values[28]:false), + 'address_state'=>(!empty($values[29])?$values[29]:false), + 'address_country'=>(!empty($values[31])?$values[31]:false), + 'postcode_home'=>(!empty($values[30])?$values[30]:false), + 'company_work'=>(!empty($values[17])?$values[17]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[21])?$values[21]:false), + 'address_work_country'=>(!empty($values[24])?$values[24]:false), + 'address_work_state'=>(!empty($values[22])?$values[22]:false), + 'address_work_postcode'=>(!empty($values[23])?$values[23]:false), + 'fax_work'=>false, + 'phone_work'=>(!empty($values[7])?$values[7]:false), + 'website'=>(!empty($values[14])?$values[14]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://mb.indiatimes.com/it/logout.jsp",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/indiatimes.plg.php b/plugins/contact_importer/OpenInviter/plugins/indiatimes.plg.php new file mode 100755 index 00000000..3304b3ed --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/indiatimes.plg.php @@ -0,0 +1,187 @@ +<?php +$_pluginInfo=array( + 'name'=>'IndiaTimes', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from an IndiaTimes account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://in.indiatimes.com/default1.cms', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * IndiaTimes Plugin + * + * Imports user's contacts from IndiaTimes' AddressBook + * + * @author OpenInviter + * @version 1.0.3 + */ +class indiatimes extends OpenInviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + + public $debug_array=array('initial_get'=>'passwd', + 'login_post'=>'Location', + 'inbox_url'=>'sunsignid="2"', + 'file_contacts'=>'email' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='indiatimes'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res = $this->get("http://in.indiatimes.com/default1.cms"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://in.indiatimes.com/default1.cms",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://in.indiatimes.com/default1.cms",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=html_entity_decode($this->getElementString($res,'return checkVal(this);" action="','"')); + $post_elements=array('login'=>$user, + 'passwd'=>$pass, + 'Sign in'=>'Sign In' + ); + + $res=$this->post($form_action,$post_elements,true); + + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $basepath=$this->getElementString($res,"Location: ",'jsp')."jsp"; + $res=$this->get($basepath,true); + + if ($this->checkResponse("inbox_url",$res)) + $this->updateDebugBuffer('inbox_url',$basepath,'GET'); + else + { + $this->updateDebugBuffer('inbox_url',$basepath,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_file_contacts=str_replace("/it/login.jsp","",$basepath)."/home/{$user}/Contacts.csv"; + + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[0])) + $contacts[$values[0]]=array('first_name'=>(!empty($values[4])?$values[0]:false), + 'middle_name'=>(!empty($values[5])?$values[2]:false), + 'last_name'=>(!empty($values[6])?$values[6]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[0])?$values[0]:false), + 'email_2'=>(!empty($values[1])?$values[1]:false), + 'email_3'=>(!empty($values[2])?$values[2]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://mb.indiatimes.com/it/logout.jsp",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/inet.plg.php b/plugins/contact_importer/OpenInviter/plugins/inet.plg.php new file mode 100755 index 00000000..be1b2489 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/inet.plg.php @@ -0,0 +1,172 @@ +<?php +$_pluginInfo=array( + 'name'=>'Inet', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Inet account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://inet.ua/index.php', + 'requirement'=>'email', + 'allowed_domains'=>array('/(inet.ua)/i','/(fm.com.ua)/i'), + ); +/** + * Inet Plugin + * + * Imports user's contacts from Inet AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class inet extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login_username', + 'login_post'=>'frame', + 'url_redirect'=>'passport', + 'url_export'=>'FORENAME', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='inet'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://inet.ua/index.php"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://inet.ua/index.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://inet.ua/index.php",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $user_array=explode('@',$user);$username=$user_array[0]; + $form_action="http://newmail.inet.ua/login.php"; + $post_elements=array('username'=>$username,'password'=>$pass,'server_id'=>0,'template'=>'v-webmail','language'=>'ru','login_username'=>$username,'servname'=>'inet.ua','login_password'=>$pass,'version'=>1,'x'=>rand(1,100),'y'=>rand(1,100)); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://newmail.inet.ua/download.php?act=process_export&method=csv&addresses=all"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_export",$res)) + $this->updateDebugBuffer('url_export',$url,'GET'); + else + { + $this->updateDebugBuffer('url_export',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $tempFile=explode(PHP_EOL,$res);$contacts=array();unset($tempFile[0]); + foreach ($tempFile as $valuesTemp) + { + $values=explode('~',$valuesTemp); + if (!empty($values[3])) + $contacts[$values[3]]=array('first_name'=>(!empty($values[1])?$values[1]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>false, + 'nickname'=>false, + 'email_1'=>(!empty($values[3])?$values[3]:false), + 'email_2'=>(!empty($values[4])?$values[4]:false), + 'email_3'=>(!empty($values[5])?$values[5]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[8])?$values[8]:false), + 'phone_home'=>(!empty($values[6])?$values[6]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[11])?$values[11]:false), + 'address_state'=>(!empty($values[12])?$values[12]:false), + 'address_country'=>(!empty($values[14])?$values[14]:false), + 'postcode_home'=>(!empty($values[13])?$values[13]:false), + 'company_work'=>false, + 'address_work'=>false, + 'address_work_city'=>false, + 'address_work_country'=>false, + 'address_work_state'=>false, + 'address_work_postcode'=>false, + 'fax_work'=>false, + 'phone_work'=>(!empty($values[7])?$values[7]:false), + 'website'=>false, + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://newmail.inet.ua/logout.php?vwebmailsession=',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/interia.plg.php b/plugins/contact_importer/OpenInviter/plugins/interia.plg.php new file mode 100755 index 00000000..d45a1a92 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/interia.plg.php @@ -0,0 +1,169 @@ +<?php +$_pluginInfo=array( + 'name'=>'Interia', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from an Interia.pl account, Plugin developed by Bartosz Zarczynski", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://poczta.interia.pl/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(interia.pl)/i', '/(poczta.fm)/i', '/(interia.eu)/i', '/(1gb.pl)/i', '/(2gb.pl)/i', '/(vip.interia.pl)/i', '/(serwus.pl)/i', '/(akcja.pl)/i', '/(czateria.pl)/i', '/(znajomi.pl)/i'), + ); +/** + * Interia.pl Plugin + * + * Imports user's contacts from Interia.pl account + * + * @author Bartosz Zarczynski + * @version 1.0.0 + */ +class interia extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + + public $debug_array=array('initial_get'=>'pocztaLoginForm', + 'login_post'=>'side-folders', + 'url_contact'=>'while(1)' + ); + private $sid; + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='interia'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res = $this->get("http://poczta.interia.pl/",true); + + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://poczta.interia.pl/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://poczta.interia.pl/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $at = strpos($user, '@'); + $domain = substr($user, $at+1, strlen($user)-$at); + + $form_action="http://ssl.interia.pl/login.html?classicMail=1"; + $post_elements=array('login'=>$user, + 'pass'=>$pass, + 'domain' => $domain, + 'htmlMail' => 'checked', + 'referer' => 'http://poczta.interia.pl/poczta/' + ); + + $res=$this->post($form_action,$post_elements, true, true, false); + + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"http://ssl.interia.pl/login.html?classicMail=1",'GET'); + else + { + $this->updateDebugBuffer('login_post',"http://ssl.interia.pl/login.html?classicMail=1",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $pos = strpos($res, "logout,uid,"); + $this->sid = substr($res, $pos+11, 16); + + $this->login_ok = "http://poczta.interia.pl/html/getcontacts,all,1,uid,$this->sid?inpl_network_request=true"; + + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + + if ($this->checkResponse("url_contact",$res)) + $this->updateDebugBuffer('url_contact',$this->login_ok,'GET'); + else + { + $this->updateDebugBuffer('url_contact',$this->login_ok,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $noheader = substr($res, strpos($res, "while(1);[{") + 11, strlen($res) - 2); + $lines = explode("},{", $noheader); + $i = 0; + foreach ($lines as $line) + { + $data[$i] = explode(",", $line); + $i++; + } + + $contacts = array(); + foreach ($data as $line=>$param) + { + foreach ($param as $x) + { + $pos_mail = strpos($x, "email"); + $email = substr($x, 9, strlen($x)-10); + $pos_firstname = strpos($x, "firstName"); + if ($pos_firstname != false) $firstname = substr($x, 13, strlen($x)-14); + $pos_lastname = strpos($x, "lastName"); + if ($pos_lastname != false) $lastname = substr($x, 12, strlen($x)-13); + if ($pos_mail != false) $contacts[$email] =array('first_name'=>$firstname,'last_name'=>$lastname,'email_1'=>$email); + } + } + + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res = $this->get("http://poczta.interia.pl/html/logout,uid,$this->sid", true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/katamail.plg.php b/plugins/contact_importer/OpenInviter/plugins/katamail.plg.php new file mode 100755 index 00000000..06176512 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/katamail.plg.php @@ -0,0 +1,154 @@ +<?php +$_pluginInfo=array( + 'name'=>'KataMail', + 'version'=>'1.0.9', + 'description'=>"Get the contacts from a KataMail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://webmail.katamail.com', + 'requirement'=>'email', + 'allowed_domains'=>array('/(katamail.com)/i'), + ); +/** + * KataMail Plugin + * + * Imports user's contacts from KataMail's AddressBook + * + * @author OpenInviter + * @version 1.0.5 + */ +class katamail extends openinviter_base +{ + private $login_ok=false; + public $showContacts=false; + private $server,$id = ""; + protected $timeout=30; + public $debug_array=array( + 'main_redirect'=>'location.href' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='katamail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $postvars = array( + "Language"=>"italiano", + "pop3host"=>"katamail.com", + "username"=>$user, + "LoginType"=>"xp", + "language"=>"italiano", + "MailType"=>"imap", + "email"=>$user."@katamail.com", + "password"=>$pass ); + $res = $this->get("http://webmail.katamail.com", true); + $res = $this->post("http://webmail.katamail.com/atmail.php", $postvars, true); + $res = htmlentities($res); + if ($this->checkResponse("main_redirect",$res)) + $this->updateDebugBuffer('main_redirect',"http://webmail.katamail.com/atmail.php",'POST'); + else + { + $this->updateDebugBuffer('main_redirect',"http://webmail.katamail.com/atmail.php",'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok = "http://webmail.katamail.com/abook.php?func=export&abookview=personal"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + { + $contacts = array(); + $res = $this->get($this->login_ok); + $temp=$this->parseCSV($res); + foreach ($temp as $values) + { + if (!empty($values[1])) + $contacts[$values[1]]=array('first_name'=>(!empty($values[6])?$values[6]:false), + 'middle_name'=>(!empty($values[18])?$values[18]:false), + 'last_name'=>(!empty($values[17])?$values[17]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[1])?$values[1]:false), + 'email_2'=>(!empty($values[2])?$values[2]:false), + 'email_3'=>(!empty($values[3])?$values[3]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[12])?$values[12]:false), + 'phone_home'=>(!empty($values[13])?$values[13]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[9])?$values[9]:false), + 'address_state'=>(!empty($values[14])?$values[14]:false), + 'address_country'=>(!empty($values[10])?$values[10]:false), + 'postcode_home'=>false, + 'company_work'=>(!empty($values[24])?$values[24]:false), + 'address_work'=>(!empty($values[22])?$values[22]:false), + 'address_work_city'=>(!empty($values[23])?$values[23]:false), + 'address_work_country'=>(!empty($values[25])?$values[25]:false), + 'address_work_state'=>(!empty($values[31])?$values[31]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + } + $this->showContacts = true; + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://webmail.katamail.com/index.php?func=logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/kids.plg.php b/plugins/contact_importer/OpenInviter/plugins/kids.plg.php new file mode 100755 index 00000000..fed7880a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/kids.plg.php @@ -0,0 +1,150 @@ +<?php +$_pluginInfo=array( + 'name'=>'Kids', + 'version'=>'1.0.1', + 'description'=>"Get the contacts from a Kids account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.kids.co.uk/email/index.php', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Kids Plugin + * + * Import user's contacts from Kids account + * + * + * @author OpenInviter + * @version 1.0.0 + */ +class kids extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login_id', + 'login_post'=>'frame', + 'url_contacts'=>'doaddresses.php?_MATRIXaction=', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='kids'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.kids.co.uk/email/index.php",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.kids.co.uk/email/index.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.kids.co.uk/email/index.php",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.kids.co.uk/email/home/dologin.php"; + $post_elements=array('did'=>2, + 'login_id'=>$user, + 'did'=>2, + 'login_pwd'=>$pass, + ); + + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_addressbook='http://www.kids.co.uk/email/home/addressbook.php'; + $this->login_ok=$url_addressbook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query);$odd=true; + foreach($data as $node) + { + if (strpos($node->getAttribute('href'),'doaddresses.php?_MATRIXaction=Modify')!==false) + { + if ($odd) $names[]=$node->nodeValue;else $emails[]=$node->nodeValue; + $odd=!$odd; + } + } + if (!empty($names)) foreach($names as $key=>$value) if(!empty($emails[$key])) $contacts[$emails[$key]]=array('first_name'=>$value,'email_1'=>$emails[$key]); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://kids.co.uk/email/dologout.php",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/kincafe.plg.php b/plugins/contact_importer/OpenInviter/plugins/kincafe.plg.php new file mode 100755 index 00000000..08c3f365 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/kincafe.plg.php @@ -0,0 +1,125 @@ +<?php +/* + * Created on Feb 10, 2009 by Vlad + */ + +$_pluginInfo=array( + 'name'=>'Kincafe', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a kincafe.com account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.kincafe.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); + +/** + * kincafe Plugin + * + * Import user's contacts from kincafe + * + * @author OpenInviter + * @version 1.0.1 + */ +class kincafe extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'login_post'=>'logout.fam', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='kincafe'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + + $res = $this->get('http://www.kincafe.com/signin.fam',true); + $post_elements = $this->getHiddenElements($res); + $post_elements['loginForm:username']=$user; + $post_elements['loginForm:pwd']=$pass; + $post_elements['loginForm:bottomSignInBtn']='+Sign+In+'; + $res = $this->post("http://www.kincafe.com/signin.fam",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"http://www.kincafe.com/signin.fam",'POST'); + else + { + $this->updateDebugBuffer('login_post',"http://www.kincafe.com/signin.fam",'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok = "http://www.kincafe.com/fammemlist.fam"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res = $this->get($url,true); + //echo $res; + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//tr[@style='background-color:#fbfbfb']";$data=$xpath->query($query); + foreach($data as $node) + { + $td=$node->childNodes; + $name = $td->item(2)->nodeValue; + $email = $td->item(6)->nodeValue; + $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.kincafe.com/logout.fam"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/konnects.plg.php b/plugins/contact_importer/OpenInviter/plugins/konnects.plg.php new file mode 100755 index 00000000..14b3e009 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/konnects.plg.php @@ -0,0 +1,204 @@ +<?php +/*Import Friends from Konnects + * You can Write Private Messages using Konnects system + */ +$_pluginInfo=array( + 'name'=>'Konnects', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Konnects account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.konnects.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Konnects Plugin + * + * Import Friends from Konnects + * You can Write Private Messages using Konnects system + * + * @author OpenInviter + * @version 1.0.0 + */ +class konnects extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'UserName', + 'login_post'=>'fncRedirect', + 'get_friends'=>'links_inbox', + 'url_friend'=>'a', + 'url_send_message'=>'a', + 'send_message'=>'sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='konnects'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.konnects.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.konnects.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.konnects.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://www.konnects.com/login.jsp?Flag=R"; + $post_elements=array('Return'=>'member_homepage.jspf', + 'UserName'=>$user, + 'Password'=>$pass + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.konnects.com/member_connections.jsp'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,"//a[@class='links_inbox']"); + $hrefs_array=$this->getElementDOM($res,"//a[@class='links_inbox']",'href'); + if (!empty($hrefs_array)) + foreach($hrefs_array as $key=>$value) $contacts[$value]=(!empty($names_array[$key])?$names_array[$key]:false); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_friend='http://www.konnects.com/'.$href; + $res=$this->get($url_friend,true); + if ($this->checkResponse("url_friend",$res)) + $this->updateDebugBuffer('url_friend',$url_friend,'GET'); + else + { + $this->updateDebugBuffer('url_friend',$url_friend,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_send_message="http://www.konnects.com/profiles_message".$this->getElementString($res,'profiles_message','"'); + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.konnects.com/'.$this->getElementString($res,'name="profile" id="profile" action="','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['Message']=$message['body']; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.konnects.com/logout.jsp"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/koolro.plg.php b/plugins/contact_importer/OpenInviter/plugins/koolro.plg.php new file mode 100755 index 00000000..8f8d8307 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/koolro.plg.php @@ -0,0 +1,181 @@ +<?php +/*Import Friends from Koolro + * You can send message to your Friends Inbox + */ +$_pluginInfo=array( + 'name'=>'Koolro', + 'version'=>'1.0.1', + 'description'=>"Get the contacts from a Koolro account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.koolro.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Koolro Plugin + * + * Imports user's contacts from Koolro and sends + * messages using Koolro's internal system. + * + * @author OpenInviter + * @version 1.0.8 + */ +class koolro extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'username', + 'login_post'=>'contacts.contacts', + 'url_friends'=>'option', + 'send_message'=>'ajFetch' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='koolro'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.koolro.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.koolro.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.koolro.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.koolro.com/index.php?L"; + $post_elements=array('username'=>$user,'password'=>$pass,'userlogin'=>false); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $url_my_friends='http://www.koolro.com/index.php?L=mails.write'; + $this->login_ok=$url_my_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//option";$data=$xpath->query($query); + foreach($data as $node) + { $value=$node->getAttribute('value');if(!empty($value)) $contacts[$value]=$value; } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach ($contacts as $name) + { + $countMessages++; + $form_action="http://www.koolro.com/index.php?L=mails.write"; + $post_elements=array('subject'=>$message['subject'], + 'body'=>$message['body'], + 'username'=>false, + 'contact'=>$name, + 'Submit'=>'Submit' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.koolro.com/index.php?logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/lastfm.plg.php b/plugins/contact_importer/OpenInviter/plugins/lastfm.plg.php new file mode 100755 index 00000000..2cfc1663 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/lastfm.plg.php @@ -0,0 +1,142 @@ +<?php +$_pluginInfo=array( + 'name'=>'Last.fm', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Last.fm account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.last.fm', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * LastFm Plugin + * + * Import user's contacts from Last.fm AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class lastfm extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + private $sess_id, $username, $siteAddr; + + public $debug_array=array( + 'login_post'=>'logout', + 'friends_url'=>'username' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='lastfm'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $post_elements=array("username"=>"{$user}", + "password"=>"{$pass}", + "backto"=>urldecode("http%3A%2F%2Fwww.last.fm%2Flogin%2FsuccessCallback")); + $res=$this->post("https://www.last.fm/login?lang=&withsid",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"https://www.last.fm/login?lang=&withsid",'POST'); + else + { + $this->updateDebugBuffer('login_post',"https://www.last.fm/login?lang=&withsid",'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok = "http://www.last.fm/inbox/compose"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + $contacts=array(); + if (preg_match_all("#\"r4\_(.+)\"\:\{\"username\"\:\"(.+)\"#U",$res,$matches)) + { + if (!empty($matches[1])) + foreach($matches[1] as $key=>$id) + if (!empty($matches[2][$key])) $contacts["r4_{$id}"]=$matches[2][$key]; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $res = $this->get("http://www.last.fm/inbox/compose"); + $postelem = $this->getHiddenElements($res); + $postelem['to']=""; + $postelem['subject']=$message['subject']; + $postelem['body']=$message['body']; + $countMessages=0; + foreach ($contacts as $id => $username) + { + $countMessages++; + $postelem['to_ids%5B%5D'] = $id; + $res = $this->post('http://www.last.fm/inbox/compose',$postelem, true, true); + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url = "http://www.last.fm/login/logout"; + $res = $this->get($logout_url); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/libero.plg.php b/plugins/contact_importer/OpenInviter/plugins/libero.plg.php new file mode 100755 index 00000000..a027b1e4 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/libero.plg.php @@ -0,0 +1,191 @@ +<?php +$_pluginInfo=array( + 'name'=>'Libero', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Libero account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://imodemail.libero.it/imodeaccess/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(libero.it)/i','/(inwind.it)/i','/(iol.it)/i','/(blu.it)/i'), + ); +/** + * Libero Plugin + * + * Imports user's contacts from Libero's AddressBook + * + * @author OpenInviter + * @version 1.0.2 + */ +class libero extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + public $debug_array=array('initial_get'=>'password', + 'post_login'=>'Location:', + 'inbox'=>'accesskey="4"', + 'contacts_page'=>'accesskey="1"', + 'contact_info'=>'Addr_ln', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='libero'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://imodemail.libero.it/imodeaccess/",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://imodemail.libero.it/imodeaccess/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://imodemail.libero.it/imodeaccess/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://imodemail.libero.it/imodemail/servlets/CliLoginImode?Act=enter"; + $domain_array=explode("@",$user);$domain=$domain_array[1];$libero_user=$domain_array[0]; + $post_elements=array( + "u"=>$libero_user, + "d"=>$domain, + "p"=>$pass, + ''=>'Entra' + ); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $base_url="http://".$this->getElementString($this->getElementString($res,"Location: ",PHP_EOL),"http://",'/'); + $url_redirect=str_replace(" [following]","",$this->getElementString($res,"Location: ",PHP_EOL)); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('inbox',$res)) + $this->updateDebugBuffer('inbox',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('inbox',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_contacts_array=$this->getElementDOM($res,"//a[@accesskey='4']",'href'); + $url_contacts=array();$url_contacts=array($base_url,$url_contacts_array[0]); + $this->login_ok=$url_contacts; + file_put_contents($this->getLogoutPath(),$url_redirect); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $res=$this->get($url[0].$url[1]); + if ($this->checkResponse('contacts_page',$res)) + $this->updateDebugBuffer('contacts_page',$url[0].$url[1],'GET'); + else + { + $this->updateDebugBuffer('contacts_page',$url[0].$url[1],'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array();$next=true; + while($next) + { + $url_next_array=$this->getElementDOM($res,"//a[@accesskey='1']",'href'); + $url_next=$url[0].$url_next_array[0]; + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + { + if (strpos($node->getAttribute('href'),'Act_Role=0')!==false) + { + $url_contact=$url[0].$node->getAttribute('href'); + $res=$this->get($url_contact,true); + if ($this->checkResponse('contact_info',$res)) + $this->updateDebugBuffer('contact_info',$url_contact,'GET'); + else + { + $this->updateDebugBuffer('contact_info',$url_contact,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $cognome=$this->getElementString($res,'name="Addr_ln" value="','"'); + $nome=$this->getElementString($res,'name="Addr_fn" value="','"'); + $alias=$this->getElementString($res,'name="Addr_alias" value="','"'); + $email=$this->getElementString($res,'Addr_mail" value="','"'); + if (!empty($email)) $contacts[$email]=array('first_name'=>$nome,'last_name'=>$cognome,'nickname'=>$alias,'email_1'=>$email); + } + } + if (!empty($url_next_array[0])) $res=$this->get($url_next,true); + else $next=false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + $res=$this->get($url,true); + $url_logout=$this->getElementDOM($res,"//a[@accesskey='8']",'href'); + $base_url="http://".$this->getElementString($url,"http://",'/'); + $res=$this->get($base_url.$url_logout[0]); + $res=$this->get("http://portal.imode.wind.it/gprs/mn/main.htm",true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/linkedin.plg.php b/plugins/contact_importer/OpenInviter/plugins/linkedin.plg.php new file mode 100755 index 00000000..f001d133 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/linkedin.plg.php @@ -0,0 +1,171 @@ +<?php +$_pluginInfo=array( + 'name'=>'LinkedIn', + 'version'=>'1.1.2', + 'description'=>"Get the contacts from a LinkedIn account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.linkedin.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * LinkedIn + * + * Imports user's email contacts from LinkedIn + * + * @author OpenInviter + * @version 1.1.1 + */ +class linkedin extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'session_password', + 'login_post'=>'window.location.replace', + 'js_page'=>'csrfToken', + 'get_friends'=>'emailAddress', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='linkedin'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://www.linkedin.com/secure/login?trk=hb_signin"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"https://www.linkedin.com/secure/login?trk=hb_signin",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://www.linkedin.com/secure/login?trk=hb_signin",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="https://www.linkedin.com/secure/login"; + $post_elements=array('csrfToken'=>'guest_token', + 'session_key'=>$user, + 'session_password'=>$pass, + 'session_login'=>'Sign In', + 'session_login'=>'', + 'session_rikey'=>'' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $res=$this->get("http://www.linkedin.com/home",true); + if ($this->checkResponse("js_page",$res)) + $this->updateDebugBuffer('js_page',"https://www.linkedin.com/secure/login?trk=hb_signin",'GET'); + else + { + $this->updateDebugBuffer('js_page',"https://www.linkedin.com/secure/login?trk=hb_signin",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->ajaxSes=$this->getElementString($res,'name="csrfToken" value="','"'); + $url_friends="http://www.linkedin.com/dwr/exec/ConnectionsBrowserService.getMyConnections.dwr"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $form_action=$this->login_ok; + $post_elements=array('callCount'=>'1', + 'JSESSIONID'=>$this->ajaxSes, + 'c0-scriptName'=>'ConnectionsBrowserService', + 'c0-methodName'=>'getMyConnections', + 'c0-param0'=>'string:0', + 'c0-param1'=>'number:-1', + 'c0-param2'=>'string:DONT_CARE', + 'c0-param3'=>'number:10000', + 'c0-param4'=>'boolean:false', + 'c0-param5'=>'boolean:true', + 'xml'=>'true', + ); + $headers = array('Content-Type'=>'text/plain'); + $res=$this->post($form_action,$post_elements,false,false,false,$headers); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('get_friends',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $cr = "/var s\\d+=\\{\\};(.*?)\\.profileLink=/ims"; + $fr = "/var s\\d+=\"([^\"]*)\";s\\d+.firstName=s\\d+/ims"; + $er = "/var s\\d+=\"([^\"]*)\";s\\d+.emailAddress=s\\d+/ims"; + $lr = "/var s\\d+=\"([^\"]*)\";s\\d+.lastName=s\\d+/ims"; + $ar = "/var s\\d+=\"([A-Z#])\";s\\d+\\[\\d+\\]=s\\d+;/ims"; + $dr = "/;s\\d+\\['([A-Z#])'\\]=s\\d+;/ims"; + preg_match_all($cr, $res, $found, PREG_SET_ORDER); + foreach ($found as $val) + { $tempHtml= $val[0];if (preg_match($er,$tempHtml,$foundEmails)) { $email=$foundEmails[1];if ($this->isEmail($email)) { $first_name=preg_match($fr,$tempHtml,$foundEmails) ? $foundEmails[1] : ''; $last_name=preg_match($lr,$tempHtml,$foundEmails) ? $foundEmails[1] : '';$last_name;$contacts[$email]=array('first_name'=>isset($first_name)?$first_name:false,'last_name'=>isset($last_name)?$last_name:false,'email_1'=>$email); } } } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("https://www.linkedin.com/secure/login?session_full_logout=&trk=hb_signout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/livejournal.plg.php b/plugins/contact_importer/OpenInviter/plugins/livejournal.plg.php new file mode 100755 index 00000000..de2c32c1 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/livejournal.plg.php @@ -0,0 +1,193 @@ +<?php +/*Import Friends from Livejournal + * You can Post Messages using Livejournal system + */ +$_pluginInfo=array( + 'name'=>'Livejournal', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Livejournal account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.livejournal.com/mobile/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Livejournal Plugin + * + * Import user's contacts from Livejournal and Post messages + * using Livejournal's internal Posting system + * + * @author OpenInviter + * @version 1.0.0 + */ +class livejournal extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'user', + 'login_post'=>'post.bml', + 'get_friends'=>'lj:user', + 'url_send_message'=>'lj_form_auth', + 'send_message'=>'successfully' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='livejuornal'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.livejournal.com/mobile/login.bml"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.livejournal.com/mobile/login.bml",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.livejournal.com/mobile/login.bml",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.livejournal.com/mobile/login.bml"; + $post_elements=array('user'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_post='http://www.livejournal.com/friends/edit.bml'; + $this->login_ok=$url_post; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $contacts_array=$this->getElementDOM($res,"//span[@class='ljuser']"); + if (!empty($contacts_array)) + foreach($contacts_array as $name) if (!empty($name)) $contacts[$name]=!empty($name)?$name:false; + unset($contacts['lj_maintenance']);unset($contacts['lj_spotlight']);unset($contacts['news']); + if (isset($contacts[$this->service_user])) unset($contacts[$this->service_user]); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $form_action='http://www.livejournal.com/inbox/compose.bml'; + $res=$this->get($form_action); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$form_action,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$form_action,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=array('lj_form_auth'=>$this->getElementString($res,'name="lj_form_auth" value="','"'), + 'msg_to'=>$name, + 'msg_subject'=>$message['subject'], + 'msg_body'=>$message['body'], + 'mode'=>'send', + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.livejournal.com/logout.bml"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/lovento.plg.php b/plugins/contact_importer/OpenInviter/plugins/lovento.plg.php new file mode 100755 index 00000000..f28d2427 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/lovento.plg.php @@ -0,0 +1,181 @@ +<?php +/*Import Friends from Lovento + * You can Write Private Messages using Lovento system + */ +$_pluginInfo=array( + 'name'=>'Lovento', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Lovento account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.lovento.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Lovento Plugin + * + * Import Friends from Lovento + * You can Write Private Messages using Lovento system + * + * @author OpenInviter + * @version 1.0.0 + */ +class lovento extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'logout', + 'get_friends'=>'to_id', + 'send_message'=>'Inbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='lovento'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.lovento.com/en/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.lovento.com/en/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.lovento.com/en/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.lovento.com/en/check_login/"; + $post_elements=array('login'=>$user, + 'password'=>$pass, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.lovento.com/en/ajax/message_center_write_mail/?to_id='; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,'//option'); + $ids_array=$this->getElementDOM($res,'//option','value'); + if (!empty($ids_array)) + foreach($ids_array as $key=>$value) $contacts[$value]=(!empty($names_array[$key])?$names_array[$key]:false); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://www.lovento.com/en/accounts/message_center/"; + $post_elements=array('doSend'=>'t', + 'to_id'=>$id, + 'message_title'=>$message['subject'], + 'message_text'=>$message['body'], + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.lovento.com/en/logout/"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/lycos.plg.php b/plugins/contact_importer/OpenInviter/plugins/lycos.plg.php new file mode 100755 index 00000000..1f1a01b9 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/lycos.plg.php @@ -0,0 +1,176 @@ +<?php +$_pluginInfo=array( + 'name'=>'Lycos', + 'version'=>'1.1.4', + 'description'=>"Get the contacts from a Lycos account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://lycos.com', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Lycos Plugin + * + * Import user's contacts from Lycos' AddressBook + * + * @author OpenInviter + * @version 1.0.9 + */ +class lycos extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'m_U', + 'login'=>'frame', + 'export_url'=>'csv', + 'file_contacts'=>'First Name' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='lycos'; + $this->service_user=$user; + $this->service_password=$pass; + $this->timeout=30; + if (!$this->init()) return false; + + $res=$this->get("http://mail.lycos.com/lycos/mail/IntroMail.lycos",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://lycos.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://lycos.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $post_elements=$this->getHiddenElements($res);$post_elements["m_U"]=$user;$post_elements["m_P"]=$pass; + $post_elements['login']='Sign In'; + $url_login="https://registration.lycos.com/login.php"; + $res=$this->post($url_login,$post_elements,true); + + if ($this->checkResponse("login",$res)) + $this->updateDebugBuffer('login',"http://registration.lycos.com/login.php?",'GET',true,$post_elements); + else + { + $this->updateDebugBuffer('login',"http://registration.lycos.com/login.php?",'GET',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_export="http://mail.lycos.com/lycos/addrbook/ExportAddr.lycos?ptype=act&fileType=OUTLOOK"; + + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $post_elements=array('ftype'=>'OUTLOOK'); + $res=$this->post($url,$post_elements); + if ($this->checkResponse("file_contacts",$res)) + { + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>(!empty($values[3])?$values[3]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[5])?$values[5]:false), + 'phone_home'=>(!empty($values[8])?$values[8]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[12])?$values[12]:false), + 'address_state'=>(!empty($values[13])?$values[13]:false), + 'address_country'=>(!empty($values[15])?$values[15]:false), + 'postcode_home'=>(!empty($values[14])?$values[14]:false), + 'company_work'=>(!empty($values[6])?$values[6]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[19])?$values[19]:false), + 'address_work_country'=>(!empty($values[22])?$values[22]:false), + 'address_work_state'=>(!empty($values[20])?$values[20]:false), + 'address_work_postcode'=>(!empty($values[21])?$values[21]:false), + 'fax_work'=>false, + 'phone_work'=>(!empty($values[7])?$values[7]:false), + 'website'=>(!empty($values[16])?$values[16]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + $this->updateDebugBuffer('file_contacts',"{$url}",'GET'); + } + else + { + $this->updateDebugBuffer('file_contacts',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("https://registration.lycos.com/logout.php",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mail2world.plg.php b/plugins/contact_importer/OpenInviter/plugins/mail2world.plg.php new file mode 100755 index 00000000..89120d95 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mail2world.plg.php @@ -0,0 +1,183 @@ +<?php +$_pluginInfo=array( + 'name'=>'Mail2World', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Mail2World account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.mail2world.com/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(mail2world.com)/i'), + ); +/** + * Mail2World Plugin + * + * Import user's contacts from Mail2World account + * + * + * @author OpenInviter + * @version 1.0.0 + */ +class mail2world extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'securebutt', + 'login_post'=>'G_ViewType', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mail2world'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mail2world.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.mail2world.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.mail2world.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $userBulk=explode('@',$user);$username=$userBulk[0];$domain=$this->getElementString($user,'@','.'); + $form_action="http://www.mail2world.com/web/app.asp?db_browser=Firefox&db_os=WIN&db_width=1280&db_height=1024"; + $post_elements=array('db_width'=>'1280', + 'db_height'=>'1024', + 'db_os'=>'WIN', + 'db_browser'=>'Firefox', + 'faction'=>'login', + 'username'=>$username, + 'domain'=>$domain, + 'password'=>$pass, + 'submitbut.x'=>rand(1,50), + 'submitbut.y'=>rand(1,50), + 'securebutt'=>'on' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_file_contacts='http://www.mail2world.com/contacts/contacts_import_export.asp?action=export&app=Outlook_2000&NewContacts=true&ContactType=all'; + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[3])) + $contacts[$values[3]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>false, + 'nickname'=>false, + 'email_1'=>(!empty($values[3])?$values[3]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.mail2world.com/logout.asp?action=logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mail_com.plg.php b/plugins/contact_importer/OpenInviter/plugins/mail_com.plg.php new file mode 100755 index 00000000..47d90e9b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mail_com.plg.php @@ -0,0 +1,194 @@ +<?php +$_pluginInfo=array( + 'name'=>'Mail.com', + 'version'=>'1.1.3', + 'description'=>"Get the contacts from a Mail.com account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.mail.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Mail.com + * + * Import user's contacts from Mail.com's AddressBook. + * + * @author OpenInviter + * @version 1.0.9 + */ +class mail_com extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'name="mailcom"', + 'login_post'=>'mailcomframe', + 'inbox'=>'outblaze', + 'export_page'=>'addrURL', + 'post_contacts'=>'csv', + 'file_contacts'=>'Title' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mail_com'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mail.com/",true); + + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.mail.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.mail.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action=$this->getElementString($res,'name="mailcom" action="','"'); + $post_elements=array("login"=>"{$user}","password"=>"{$pass}","redirlogin"=>1,"siteselected"=>"normal"); + $res=$this->post($form_action,$post_elements,true); + + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_redirect=$this->getElementDOM($res,"//frame[@name='mailcomframe']",'src'); + $res=$this->get($url_redirect[0],true); + + $this->login_ok=$url_redirect[0]; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + + if ($this->checkResponse('inbox',$res)) + $this->updateDebugBuffer('login_post',"{$url}",'GET'); + else + { + $this->updateDebugBuffer('login_post',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_contacts=$this->getElementDOM($res,"//a[@id='addrURL']",'href'); + $res=$this->get($url_contacts[0],true); + + if ($this->checkResponse("export_page",$res)) + { + $url_export=""; + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@href]";$data=$xpath->query($query); + foreach($data as $val) + if (strstr($val->nodeValue,"Import/Export")) $url_export=$val->getAttribute('href')."&gab=1"; + $this->updateDebugBuffer('post_contacts',"{$url_contacts[0]}",'GET'); + } + else + { + $this->updateDebugBuffer('post_contacts',"{$url_contacts[0]}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $post_elements=array("showexport"=>"showexport","action"=>"export","format"=>"csv"); + $res=$this->post($url_export,$post_elements); + + if ($this->checkResponse('file_contacts',$res)) + { + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + $name=$values['0'].(empty($values['1'])?'':(empty($values['0'])?'':'-')."{$values['1']}").(empty($values['3'])?'':" \"{$values['3']}\"").(empty($values['2'])?'':' '.$values['2']); + if (!empty($values['4'])) + $contacts[$values['4']]=(empty($name)?$values['4']:$name); + if (!empty($values['12'])) + $contacts[$values['12']]=(empty($name)?$values['12']:$name); + if (!empty($values['13'])) + $contacts[$values['13']]=(empty($name)?$values['13']:$name); + } + + //full description + $teM=explode(PHP_EOL,$res);$arrayDescriptionFlag=explode(',',$teM[0]); + foreach($temp as $tempA) + { + $name=$tempA['0'].(empty($tempA['1'])?'':(empty($tempA['0'])?'':'-')."{$tempA['1']}").(empty($tempA['3'])?'':" \"{$tempA['3']}\"").(empty($tempA['2'])?'':' '.$tempA['2']); + foreach ($arrayDescriptionFlag as $key=>$value) + $descriptionArray[(!empty($name)?$name:(!empty($tempA[4])?$tempA[4]:false))][$value]=isset($tempA[$key])?$tempA[$key]:false; + } + //print_R($descriptionArray); + + $this->updateDebugBuffer('login_post',"{$url_export}",'POST',true,$post_elements); + } + else + { + $this->updateDebugBuffer('login_post',"{$url_export}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $descriptionArray; + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.mail.com/logout.aspx"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mail_in.plg.php b/plugins/contact_importer/OpenInviter/plugins/mail_in.plg.php new file mode 100755 index 00000000..4053eabb --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mail_in.plg.php @@ -0,0 +1,140 @@ +<?php +$_pluginInfo=array( + 'name'=>'Mail.in', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Mail.in account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://mail.in.com/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(in.com)/i'), + ); +/** + * Mail_in Plugin + * + * Imports user's contacts from Mail.in's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class mail_in extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'frmloginverify', + 'post_login'=>'inboxmailshide', + 'contacts_page'=>'displaycontacts', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='mail_in'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://mail.in.com/"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://mail.in.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://mail.in.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action='http://mail.in.com'.$this->getElementString($res,'name="frmloginverify" method="POST" action="','"'); + $post_elements=array('f_sourceret'=>'http://mail.in.com/mails/mailstartup','f_id'=>$user,'f_pwd'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contacts='http://mail.in.com/mails/getcontacts.php'; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('contacts_page',$res)) + $this->updateDebugBuffer('contacts_page',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_page',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//td";$data=$xpath->query($query); + foreach($data as $node) + { + if (strpos($node->getAttribute('onclick'),'displaycontacts')!==false) + { + $name=$node->nodeValue; + $email_array=explode("'",(string)$node->getAttribute('onclick')); + if (!empty($email_array[1])) $contacts[$email_array[1]]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email_array[1]); + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://mail.in.com/logout',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/mail_ru.plg.php b/plugins/contact_importer/OpenInviter/plugins/mail_ru.plg.php new file mode 100755 index 00000000..3fcef7f2 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mail_ru.plg.php @@ -0,0 +1,173 @@ +<?php +$_pluginInfo=array( + 'name'=>'Mail.ru', + 'version'=>'1.1.2', + 'description'=>"Get the contacts from a Mail.ru account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.mail.ru', + 'requirement'=>'email', + 'allowed_domains'=>array('/(in.com)/i','/(list.ru)/i','/(inbox.ru)/i','/(bk.ru)/i','/(mail.ru)/i'), + ); +/** + * Mail.ru Plugin + * + * Import user's contacts from Mail.ru's AddressBook + * + * @author OpenInviter + * @version 1.0.9 + */ +class mail_ru extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'mra_confirm', + 'file_contacts'=>'"' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mail_ru'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mail.ru/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.mail.ru/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.mail.ru/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $array_user=explode("@",$user);$domain=strtolower($array_user[1]); + $hidden_element=$this->getElementDOM($res,"//input[@name='Mpopl']","value"); + $post_elements=array('Domain'=>$domain,'Login'=>$user,'Password'=>$pass,'Mpopl'=>$hidden_element[0]); + $res=$this->post("http://win.mail.ru/cgi-bin/auth",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"http://win.mail.ru/cgi-bin/auth",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"http://win.mail.ru/cgi-bin/auth",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_export="http://win.mail.ru/cgi-bin/abexport/addressbook.csv"; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $post_elements=array("confirm"=>"1","abtype"=>"1"); + $res=$this->post($url,$post_elements); + if ($this->checkResponse("file_contacts",$res)) + { + $temp=$this->parseCSV($res);$teM=explode(PHP_EOL,$res);$arrayDescriptionFlag=explode(',',$teM[0]);print_R($arrayDescriptionFlag); + $contacts=array(); + foreach ($temp as $values) + { + $contacts[$values[8]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[8])?$values[8]:false), + 'email_2'=>(!empty($values[9])?$values[9]:false), + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + $this->updateDebugBuffer('file_contacts',"{$url}",'POST',true,$post_elements); + } + else + { + $this->updateDebugBuffer('file_contacts',"{$url}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://win.mail.ru/cgi-bin/logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/meinvz.plg.php b/plugins/contact_importer/OpenInviter/plugins/meinvz.plg.php new file mode 100755 index 00000000..08dd9d7a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/meinvz.plg.php @@ -0,0 +1,202 @@ +<?php +/*Import Friends from Meinvz + * You can send message to your MeinVz Inbox + */ +$_pluginInfo=array( + 'name'=>'Meinvz', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a MeinVz account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.meinvz.net/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * MeinVz Plugin + * + * Import user's contacts from MeinVz and send + * messages using the internal messaging system + * + * @author OpenInviter + * @version 1.0.0 + */ +class meinvz extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'password', + 'login_post'=>'Friends', + 'url_friends'=>'name', + 'url_send_message'=>'Messages_searchfield', + 'send_message'=>'SendSuccessAd' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='meinvz'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.meinvz.net/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.meinvz.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.meinvz.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="https://secure.meinvz.net/Login "; + $post_elements=array('email'=>$user,'password'=>$pass,'login'=>'Login','jsEnabled'=>'true','ipRestriction'=>1,'formkey'=>$this->getElementString($res,'name="formkey" value="','"'),'iv'=>$this->getElementString($res,'name="iv" value="','"')); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_logout='http://www.meinvz.net/Logout/'.$this->getElementString($res,'<li><a href="/Logout/','"'); + $url_friends='http://www.meinvz.net/Messages/WriteMessage'; + $this->login_ok=$url_friends; + file_put_contents($this->getLogoutPath(),$url_logout); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + if (preg_match_all("#\&\#34\;name\&\#34\;\:\&\#34\;(.+)\&\#34\;\,\&\#34\;profile\&\#34\;\:\&\#34\;\\\/Profile\\\/(.+)\&\#34\;#U",$res,$matches)) + { + if (!empty($matches[2])) + foreach($matches[2] as $key=>$id) + if (!empty($matches[1][$key])) $contacts[$id]=$matches[1][$key]; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message="http://www.meinvz.net{$href}"; + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',"shttp://www.bebo.com/",'GET'); + else + { + $this->updateDebugBuffer('url_send_message',"http://www.bebo.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action=$url_send_message; + $formkey_array=$this->getElementDOM($res,"//input[@name='formkey']",'value'); + $checkcode_array=$this->getElementDOM($res,"//input[@name='checkcode']",'value'); + $iv_array=$this->getElementDOM($res,"//input[@name='iv']",'value'); + $post_elements=array('recipientIds[]'=>$this->getElementString($res,'friendList" value="{"','"'), + 'subject'=>$message['subject'], + 'message'=>$message['body'], + 'recipientIdForHistory'=>$this->getElementString($res,'friendList" value="{"','"'), + 'formkey'=>$formkey_array[1], + 'iv'=>$iv_array[1], + 'checkcode'=>$checkcode_array[1], + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout=file_get_contents($this->getLogoutPath()); + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/meta.plg.php b/plugins/contact_importer/OpenInviter/plugins/meta.plg.php new file mode 100755 index 00000000..3430441a --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/meta.plg.php @@ -0,0 +1,172 @@ +<?php +$_pluginInfo=array( + 'name'=>'Meta', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Meta account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://meta.ua/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Meta Plugin + * + * Imports user's contacts from Meta AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class meta extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'INBOX', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='meta'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://meta.ua/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://meta.ua/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://meta.ua/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://passport.meta.ua/"; + $post_elements=array('login'=>$user,'password'=>$pass,'mode'=>'login','from'=>'mail','lifetime'=>'alltime','subm'=>'Enter'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok=true; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://webmail.meta.ua/adress_transfer.php"; + $post_elements=array('mail_client'=>'outlook_en','js_enable'=>false,'action'=>'export','groups[]'=>'all','subm'=>true); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('file_contacts',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array();$tempFile=explode(PHP_EOL,$res);unset($tempFile[0]); + foreach ($tempFile as $valuesTemp) + { + $values=explode(';',$valuesTemp); + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>(!empty($values[5])?$values[5]:false), + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[13])?$values[13]:false), + 'phone_home'=>(!empty($values[11])?$values[11]:false), + 'pager'=>(!empty($values[23])?$values[23]:false), + 'address_home'=>false, + 'address_city'=>(!empty($values[7])?$values[7]:false), + 'address_state'=>(!empty($values[9])?$values[9]:false), + 'address_country'=>(!empty($values[10])?$values[10]:false), + 'postcode_home'=>(!empty($values[8])?$values[8]:false), + 'company_work'=>(!empty($values[24])?$values[24]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[18])?$values[18]:false), + 'address_work_postcode'=>(!empty($values[17])?$values[17]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[14])?$values[14]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://webmail.meta.ua/logout.php',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mevio.plg.php b/plugins/contact_importer/OpenInviter/plugins/mevio.plg.php new file mode 100755 index 00000000..370221c6 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mevio.plg.php @@ -0,0 +1,209 @@ +<?php +/*Import Friends from Mevio + * You can Send Private Messages using mevio system + */ +$_pluginInfo=array( + 'name'=>'Mevio', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Mevio account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.mevio.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Mvio Plugin + * + * Import user's contacts from Mevio and send Private messages + * using Mevio system + * + * @author OpenInviter + * @version 1.0.0 + */ +class mevio extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + + public $debug_array=array( + 'initial_get'=>'username', + 'login_post'=>'activePersona=', + 'url_home'=>'selected nobg', + 'get_friends'=>'laminate-std-name', + 'url_friend'=>'personaId', + 'url_send_message'=>'subject', + 'send_message'=>'message sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mevio'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mevio.com/login/#loginOverlay",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://us.cyworld.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://us.cyworld.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.mevio.com/login/#loginOverlay"; + $post_elements=array('username'=>$user,'password'=>$pass,'LoginSubmit'=>'Log In'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_profile='http://www.mevio.com/mc/digs/?control=Digs&action=editDigs&digMode=entourage&activePersona='.$this->getElementString($res,'http://www.mevio.com/mc/digs/?control=Digs&action=editDigs&digMode=entourage&activePersona=','"'); + $this->login_ok=$url_profile; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='laminate-std-name']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->childNodes->item(1)->nodeValue; + $href=$node->childNodes->item(1)->getAttribute('href'); + if (!empty($href)) $contacts[$href]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $res=$this->get($href,true); + if ($this->checkResponse("url_friend",$res)) + $this->updateDebugBuffer('url_friend',$href,'GET'); + else + { + $this->updateDebugBuffer('url_friend',$href,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $friend_id=$this->getElementString($res,'"personaId":"','"'); + $url_send_message='http://www.mevio.com/u2u/?class=NewTextMessage&method=auto_compose&to_select='.$friend_id; + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.mevio.com/u2u/?class=NewTextMessage&method=send"; + $post_elements=array( 'to_select[]'=>$friend_id, + 'subject'=>$message['subject'], + 'body'=>$message['body'], + 'response'=>'message_center' + ); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.mevio.com/login/?mode=logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/motortopia.plg.php b/plugins/contact_importer/OpenInviter/plugins/motortopia.plg.php new file mode 100755 index 00000000..171edf2c --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/motortopia.plg.php @@ -0,0 +1,179 @@ +<?php +/*Import Friends from Motortopia + * You can Write Private Messages using Motortopia system + */ +$_pluginInfo=array( + 'name'=>'Motortopia', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Motortopia account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.motortopia.com/main/cars', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Motortopia Plugin + * + * Import Friends from Motortopia + * You can Write Private Messages using Motortopia system + * + * @author OpenInviter + * @version 1.0.0 + */ +class motortopia extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'email', + 'login_post'=>'logout', + 'get_friends'=>'Go to this person', + 'send_message'=>'inbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='motortopia'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.motortopia.com/main/cars",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.motortopia.com/en/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.motortopia.com/en/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.motortopia.com/user/login/main/y"; + $post_elements=array('email'=>$user, + 'password'=>$pass, + 'submit'=>'Login', + 'token'=>$this->getElementString($res,'name="token" value="','"') + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.motortopia.com/friend/browse/u/'.$this->getElementString($res,'/friend/browse/u/','"'); + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,"//dd[@class='allHead']"); + if (!empty($names_array)) + foreach($names_array as $key=>$value) $contacts[$value]=$value; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $name) + { + $countMessages++; + $form_action="http://www.motortopia.com/mail/send/{$name}"; + $post_elements=array('subject'=>$message['subject'],'body'=>$message['body'],'submit'=>'Send'); + $res=$this->post($form_action,$post_elements,true); + + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.motortopia.com/user/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/multiply.plg.php b/plugins/contact_importer/OpenInviter/plugins/multiply.plg.php new file mode 100755 index 00000000..9b78d205 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/multiply.plg.php @@ -0,0 +1,192 @@ +<?php +/*Import Friends from Multiply + * You can Write Private Messages using Multiply system + */ +$_pluginInfo=array( + 'name'=>'Multiply', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a Multiply account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://multiply.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Multiply Plugin + * + * Import Friends from Multiply + * You can Write Private Messages using Multiply system + * + * @author OpenInviter + * @version 1.0.0 + */ +class multiply extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'signin::id', + 'login_post'=>'logout', + 'get_friends'=>'contactbox', + 'url_send_message'=>'form::subject', + 'send_message'=>'Inbox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='multiply'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://multiply.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.multiply.com/en/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.multiply.com/en/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://multiply.com/user/signin"; + $post_elements=$this->getHiddenElements($res);$post_elements['signin::id']=$user;$post_elements['signin::password']=$pass;$post_elements['signin::remember']='on';$post_elements['omniture_submission']='submitted'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contacts="http://{$user}.multiply.com/contacts"; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='contactbox']";$data=$xpath->query($query); + foreach($data as $node) + { + $href=$node->firstChild->getAttribute('href'); + $name=trim($this->getElementString($href,'http://','.multiply.com')); + if (!empty($href)) $contacts[$href]=utf8_decode($name); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $send_message_url="http://multiply.com/compose/pm?individual={$name}"; + $res=$this->get($send_message_url,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$send_message_url,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$send_message_url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://multiply.com/compose/pm"; + $post_elements=$this->getHiddenElements($res);$post_elements['form::subject']=$message['subject'];$post_elements['form::body']=$message['body'];$post_elements['form::Send Personal Message']=' Send Personal Message '; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://multiply.com/user/signout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mycatspace.plg.php b/plugins/contact_importer/OpenInviter/plugins/mycatspace.plg.php new file mode 100755 index 00000000..43ce6af0 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mycatspace.plg.php @@ -0,0 +1,179 @@ +<?php +/*Import Friends from mycatspace + * You can Write Private Messages using mycatspace system + */ +$_pluginInfo=array( + 'name'=>'Mycatspace', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a mycatspace account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.mycatspace.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Mycatspace Plugin + * + * Import Friends from Mycatspace.com + * You can Write Private Messages using Mycatspace system + * + * @author OpenInviter + * @version 1.0.0 + */ +class mycatspace extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'username', + 'login_post'=>'/account/logout', + 'get_friends'=>'receiver_id', + 'send_message'=>'was sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mycatspace'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mycatspace.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.mycatspace.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.mycatspace.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.mycatspace.com/account/login"; + $post_elements=array('username'=>$user,'password'=>$pass,'x'=>rand(1,100),'y'=>rand(1,100)); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.mycatspace.com/email/compose'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $names_array=$this->getElementDOM($res,'//option'); + $ids_array=$this->getElementDOM($res,'//option','value'); + foreach($ids_array as $key=>$value) + if (!empty($value)) $contacts[$value]=$names_array[$key]; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://www.mycatspace.com/email/compose"; + $post_elements=array('email[receiver_id]'=>$id, + 'email[subject]'=>$message['subject'], + 'email[content]'=>$message['body'], + 'x'=>rand(1,100), + 'y'=>rand(1,100) + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.mycatspace.com/account/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mydogspace.plg.php b/plugins/contact_importer/OpenInviter/plugins/mydogspace.plg.php new file mode 100755 index 00000000..0b8722f4 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mydogspace.plg.php @@ -0,0 +1,179 @@ +<?php +/*Import Friends from mydogspace + * You can Write Private Messages using mydogspace system + */ +$_pluginInfo=array( + 'name'=>'Mydogspace', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from a mydogspace account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.mydogspace.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Mydogspace Plugin + * + * Import Friends from Mydogspace.com + * You can Write Private Messages using Mydogspace system + * + * @author OpenInviter + * @version 1.0.0 + */ +class mydogspace extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'username', + 'login_post'=>'/account/logout', + 'get_friends'=>'receiver_id', + 'send_message'=>'was sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='mydogspace'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.mydogspace.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.mydogspace.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.mydogspace.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.mydogspace.com/account/login"; + $post_elements=array('username'=>$user,'password'=>$pass,'x'=>rand(1,100),'y'=>rand(1,100)); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.mydogspace.com/email/compose'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $names_array=$this->getElementDOM($res,'//option'); + $ids_array=$this->getElementDOM($res,'//option','value'); + foreach($ids_array as $key=>$value) + if (!empty($value)) $contacts[$value]=$names_array[$key]; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://www.mydogspace.com/email/compose"; + $post_elements=array('email[receiver_id]'=>$id, + 'email[subject]'=>$message['subject'], + 'email[content]'=>$message['body'], + 'x'=>rand(1,100), + 'y'=>rand(1,100) + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.mydogspace.com/account/logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/mynet.plg.php b/plugins/contact_importer/OpenInviter/plugins/mynet.plg.php new file mode 100755 index 00000000..0382ead6 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/mynet.plg.php @@ -0,0 +1,208 @@ +<?php +$_pluginInfo=array( + 'name'=>'Mynet.com', + 'version'=>'1.0.4', + 'description'=>"Get the contacts from an Mynet account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://uyeler.mynet.com/login/?loginRequestingURL=http%3A%2F%2Feposta.mynet.com%2Findex%2Fmymail.html&formname=eposta', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Mynet Plugin + * + * Imports user's contacts from Mynet + * + * @author OpenInviter + * @version 1.0.0 + */ +class mynet extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'faultyUser', + 'post_login'=>'mymail', + 'url_adress'=>'adres', + 'url_file'=>'adres', + 'file_contacts'=>'Name' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='mynet'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res = $this->get("http://uyeler.mynet.com/login/?loginRequestingURL=http%3A%2F%2Feposta.mynet.com%2Findex%2Fmymail.html&formname=eposta"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://uyeler.mynet.com/login/?loginRequestingURL=http%3A%2F%2Feposta.mynet.com%2Findex%2Fmymail.html&formname=eposta",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://uyeler.mynet.com/login/?loginRequestingURL=http%3A%2F%2Feposta.mynet.com%2Findex%2Fmymail.html&formname=eposta",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://uyeler.mynet.com/index/uyegiris.html"; + $post_elements=array('nameofservice'=>'epost', + 'pageURL'=>'http://uyeler.mynet.com/login/login.asp?loginRequestingURL=http%3A%2F%2Feposta.mynet.com%2Findex%2Fmymail.html&formname=eposta', + 'faultCoun'=>'', + 'faultyUser'=>'', + 'loginRequestingURL'=>'http://eposta.mynet.com/index/mymail.html', + 'rememberstate'=>2, + 'username'=>$user, + 'password'=>$pass, + 'x'=>rand(1,50), + 'y'=>rand(1,20), + 'rememberstatep'=>2 + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $res=$this->get("http://eposta.mynet.com/index/mymail.html",true); + $base_url="http://".$this->getElementString($res,"var mySrvName = '","'").".mynet.com"; + if ($this->checkResponse('url_adress',$res)) + $this->updateDebugBuffer('url_adress',"http://eposta.mynet.com/index/mymail.html",'GET'); + else + { + $this->updateDebugBuffer('url_adress',"http://eposta.mynet.com/index/mymail.html",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_adressbook='http://adres.email'.$this->getElementString($res,'http://adres.email','"'); + $res=$this->get($url_adressbook); + if ($this->checkResponse('url_file',$res)) + $this->updateDebugBuffer('url_file',$url_adressbook,'GET'); + else + { + $this->updateDebugBuffer('url_file',$url_adressbook,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_file_contacts="http://adres.email.mynet.com/Exim/ExportFileDownload.aspx?format=microsoft_csv"; + $this->login_ok=$url_file_contacts; + file_put_contents($this->getLogoutPath(),$base_url); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('file_contacts',$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[9])) + $contacts[$values[9]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>false, + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[9])?$values[9]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[7])?$values[7]:false), + 'phone_home'=>(!empty($values[6])?$values[6]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>false, + 'address_state'=>false, + 'address_country'=>false, + 'postcode_home'=>(!empty($values[4])?$values[4]:false), + 'company_work'=>(!empty($values[2])?$values[2]:false), + 'address_work'=>false, + 'address_work_city'=>false, + 'address_work_country'=>false, + 'address_work_state'=>false, + 'address_work_postcode'=>false, + 'fax_work'=>false, + 'phone_work'=>false, + 'website'=>false, + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout=file_get_contents($this->getLogoutPath())."/webmail/src/signout.php"; + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/myspace.plg.php b/plugins/contact_importer/OpenInviter/plugins/myspace.plg.php new file mode 100755 index 00000000..a5d20cc8 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/myspace.plg.php @@ -0,0 +1,200 @@ +<?php +$_pluginInfo=array( + 'name'=>'MySpace', + 'version'=>'1.0.8', + 'description'=>"Get the contacts from a MySpace account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.myspace.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * MySpace Plugin + * + * Import user's contacts from MySpace and send + * messages using the internal messaging system + * + * @author OpenInviter + * @version 1.0.5 + */ +class myspace extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'__VIEWSTATE', + 'login'=>'Compose', + 'get_url_friends'=>'profile.interests', + 'url_friends'=>'friendHelperBox' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='myspace'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.myspace.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.myspace.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.myspace.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://secure.myspace.com/index.cfm?fuseaction=login.process"; + $post_elements=array('__VIEWSTATE'=>$this->getElementString($res,'id="__VIEWSTATE" value="','"'), + 'NextPage'=>'', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_Email_Textbox'=>$user, + 'ctl00_ctl00_cpMain_cpMain_LoginBox_Password_Textbox'=>$pass, + 'dlb'=>'Log In', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_SingleSignOnHash'=>'', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_SingleSignOnRequestUri'=>'', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_nexturl'=>'', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_apikey'=>'', + 'ctl00_ctl00_cpMain_cpMain_LoginBox_ContainerPage'=>'' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("get_url_friends",$res)) + $this->updateDebugBuffer('get_url_friends',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('get_url_friends',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends="http://friends.myspace.com/index.cfm?fuseaction=user.viewfriends&friendID=".$this->getElementString($res,'"UserId":',','); + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $has_next=true;$page=-1;$contacts=array(); + do + { + if (strpos($res,'nextPagingLink disabledPaging')!==false) $has_next=false; + else + { + $page++; + $page_next=$this->getElementString($res,"var urlHelper = new FriendsCategories.UrlHelper('","'"); + $fid=$this->getElementString($res,"urlHelper.SetQueryValue('fid', '","'"); + $lid=$this->getElementString($res,"urlHelper.SetQueryValue('lid', '","'"); + $page_next.="&p={$page}&j=1&fid={$fid}&lid={$lid}"; + $res=$this->get($page_next,true); + } + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='friendHelperBox']";$data=$xpath->query($query); + foreach ($data as $node) + $contacts[$node->getAttribute('friendid')]=(string)$node->nodeValue; + } + while($has_next); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $res=$this->get("http://friends.myspace.com/index.cfm?fuseaction=user.viewfriends&friendID=",true); + $mytokenvar=$this->getElementString($res,"MyToken=","')"); + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $url_messaging="http://messaging.myspace.com/index.cfm?fuseaction=mail.message&friendID={$id}&MyToken={$mytokenvar}"; + $res=$this->get($url_messaging,true); + $post_elements=array('__LASTFOCUS'=>'', + '__EVENTTARGET'=>'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$btnSend', + '__EVENTARGUMENT'=>'', + '__VIEWSTATE'=>$this->getElementString($res,'id="__VIEWSTATE" value="','"'), + '___msUniqueVal'=>$this->getElementString($res,'id="___msUniqueVal" value="','"'), + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$selectedRecipient'=>'', + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$selectedRecipientName'=>'', + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$subjectTextBox'=>$message['subject'], + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$ieHack'=>'', + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$bodyTextBox'=>$message['body'], + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$saveDraftGuid'=>'', + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$MessageInfoData'=>'', + 'ctl00$ctl00$ctl00$cpMain$cpMain$messagingMain$SendMessage$FriendInfoData'=>$this->getElementString($res,'id="ctl00_ctl00_ctl00_cpMain_cpMain_messagingMain_SendMessage_FriendInfoData" value="','"'), + ); + $res=$this->post($url_messaging,$post_elements,true); + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.myspace.com/index.cfm?fuseaction=signout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/netaddress.plg.php b/plugins/contact_importer/OpenInviter/plugins/netaddress.plg.php new file mode 100755 index 00000000..9e418140 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/netaddress.plg.php @@ -0,0 +1,195 @@ +<?php +$_pluginInfo=array( + 'name'=>'Netaddress', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Netaddress account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'https://www.netaddress.com/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(netaddress.com)/i'), + ); +/** + * Netadress Plugin + * + * Imports user's contacts from Netaddress's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class netaddress extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'UserID', + 'post_login'=>'Door', + 'contacts_page'=>'fileformat', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='netaddress'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://www.netaddress.com/"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"https://www.netaddress.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://www.netaddress.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='https://www.netaddress.com/tpl/Door/LoginPost'; + $post_elements=array('UserID'=>$user, + 'passwd'=>$pass, + 'LoginState'=>2, + 'SuccessfulLogin'=>'/tpl', + 'NewServerName'=>'www.netaddress.com', + 'JavaScript'=>'JavaScript1.2', + 'DomainID'=>$this->getElementString($res,'"DomainID" value="','"'), + 'Domain'=>$this->getElementString($res,'"Domain" value="','"') + ); + $res=$this->post($form_action,$post_elements,true); + $session_id=$this->getElementString($res,'/Door/','/'); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok=$session_id; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $id=$this->login_ok; + $url_export="http://www.netaddress.com/icalphp/exportcontact.php?sid={$id}"; + $res=$this->get($url_export); + if ($this->checkResponse('contacts_page',$res)) + $this->updateDebugBuffer('contacts_page',$url_export,'GET'); + else + { + $this->updateDebugBuffer('contacts_page',$url_export,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.netaddress.com/icalphp/exportcontact.php'; + $post_elements=array('sid'=>$id,'fileformat'=>'csv1','csv1charset'=>'UTF-8'); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse('file_contacts',$res)) + $this->updateDebugBuffer('file_contacts',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('file_contacts',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res);$teM=explode(PHP_EOL,$res);$arrayDescriptionFlag=explode(',',$teM[0]);print_R($arrayDescriptionFlag); + $contacts=array(); + foreach ($temp as $values) + { + $name=$values[1].(empty($values[2])?'':(empty($values[1])?'':'-')."{$values[2]}").(empty($values[3])?'':" \"{$values[3]}\""); + if (!empty($values[5])) + $contacts[$values[5]]=(empty($name)?$values[5]:$name); + + if (!empty($values[5])) + $descriptionArray[$values[5]]=array('first_name'=>(!empty($values[1])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[3])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[5])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + + print_R($descriptionArray); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $descriptionArray; + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://mail.in.com/logout',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/netlog.plg.php b/plugins/contact_importer/OpenInviter/plugins/netlog.plg.php new file mode 100755 index 00000000..6d5dd439 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/netlog.plg.php @@ -0,0 +1,172 @@ +<?php +$_pluginInfo=array( + 'name'=>'NetLog', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from a NetLog account And Shout a message to your friends", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://en.netlog.com/m/login', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Netlog Plugin + * + * Import Friends from Netlog + * You can Shouts Messages to your friends using Netlog system + * + * @author OpenInviter + * @version 1.0.0 + */ +class netlog extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'target', + 'login_post'=>'messages', + 'get_friends'=>'option', + 'send_message'=>'success', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='netlog'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get('http://en.netlog.com/m/login'); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://en.netlog.com/m/login",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://en.netlog.com/m/login",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://en.netlog.com/m/login"; + $post_elements=array('action'=>'login','target'=>$this->getElementString($res,'name="target" value="','"'),'nickname'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://en.netlog.com/m/messages/send"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//option";$data=$xpath->query($query); + foreach($data as $node) + { + $user=$node->getAttribute('value');$name=$node->nodeValue; + if (strpos($name,'Album >')===false) if (!empty($user)) $contacts[$user]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $user=>$name) + { + $countMessages++; + $form_action="http://en.netlog.com/m/shouts/add"; + $post_elements=array('nickname'=>$user,'action'=>'__button','shout'=>$message['body'],'__btaAddShout'=>'Shout'); + $res=$this->post($form_action,$post_elements,true,true); + if (strpos($res,'warning')===false) + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url = "http://en.netlog.com/m/login/action=logout"; + $res = $this->get($logout_url); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/ning.plg.php b/plugins/contact_importer/OpenInviter/plugins/ning.plg.php new file mode 100755 index 00000000..a90edecf --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/ning.plg.php @@ -0,0 +1,166 @@ +<?php +/*Import Friends from ning + * You can Update your status using ning system + */ +$_pluginInfo=array( + 'name'=>'Ning', + 'version'=>'1.0.1', + 'description'=>"Get the contacts from a ning account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.ning.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Ning Plugin + * + * Import Friends from Ning + * You can Write Private Messages using Brazencareerist system + * + * @author OpenInviter + * @version 1.0.0 + */ +class ning extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'signin_password', + 'login_post'=>'xn_signout', + 'get_friends'=>'tb', + 'send_message'=>'200 ' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='ning'; + $this->service_user=$user; + $this->service_password=$pass; + + if (!$this->init()) return false; + + $res=$this->get("http://www.ning.com/main/signin",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.brazencareerist.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://www.ning.com/main/signin?area=System_SignIn"; + $post_elements=array('target'=>'http://www.ning.com/', + 'emailAddress'=>$user, + 'password'=>$pass, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://www.ning.com/'.$this->getElementString($res,'id="xn_username">','<')."/friends"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='tb']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->childNodes->item(1)->nodeValue; + if (!empty($name)) $contacts[$name]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $res=$this->get("http://www.ning.com"); + $form_action="http://www.ning.com/main/ajax?area=Status"; + $post_elements=array("status"=>$message['body'],'xp_token'=>$this->getElementString($res,'"xp_token" value="','"')); + $res=$this->post($form_action,$post_elements,true); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.ning.com/main/signout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/nz11.plg.php b/plugins/contact_importer/OpenInviter/plugins/nz11.plg.php new file mode 100755 index 00000000..6079e63b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/nz11.plg.php @@ -0,0 +1,150 @@ +<?php +$_pluginInfo=array( + 'name'=>'Nz11', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Nz11 account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://nz11.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Netadress Plugin + * + * Imports user's contacts from Netaddress's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class nz11 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'loginName', + 'post_login'=>'oi_sda_firstname', + 'contacts_page'=>'entriesPerPage2', + 'all_contacts'=>'entriesPerPage2', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='nz11'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://nz11.mail.everyone.net/email/scripts/loginuser.pl"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://nz11.mail.everyone.net/email/scripts/loginuser.pl",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://nz11.mail.everyone.net/email/scripts/loginuser.pl",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action='http://nz11.mail.everyone.net/email/scripts/loginuser.pl?'.$this->getElementString($res,' name="myForm" method="post" action="loginuser.pl?','"'); + $post_elements=array('loginName'=>$user,'user_pwd'=>$pass,'login'=>'Login'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok='http://nz11.mail.everyone.net/email/scripts/contacts.pl'; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('contacts_page',$res)) + $this->updateDebugBuffer('contacts_page',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_page',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action='http://nz11.mail.everyone.net/email/scripts/contacts.pl'; + $post_elements=$this->getHiddenElements($res);$post_elements['entriesPerPage2']='All'; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse('all_contacts',$res)) + $this->updateDebugBuffer('all_contacts',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('all_contacts',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array();$contacts_bulk=""; + $contacts_array=$this->getElementDOM($res,"//a",'href'); + foreach ($contacts_array as $contacts_string) + if (strpos($contacts_string,'javascript:composeMe')!==false) + { + $contacts_bulk=$this->getElementString($contacts_string,"'",'>'); + $contacts_bulk=str_replace('"','',$contacts_bulk); + $contacts_explode=explode('<',$contacts_bulk); + if (isset($contacts_explode[1])) + $contacts[$contacts_explode[1]]=array('first_name'=>(isset($contacts_explode[0])?$contacts_explode[0]:false),'email_1'=>$contacts_explode[1]); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://nz11.mail.everyone.net/email/scripts/logout.pl'); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/o2.plg.php b/plugins/contact_importer/OpenInviter/plugins/o2.plg.php new file mode 100755 index 00000000..c9138480 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/o2.plg.php @@ -0,0 +1,174 @@ +<?php +$_pluginInfo=array( + 'name'=>'O2', + 'version'=>'1.0.1', + 'description'=>"Get the contacts from a O2 account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://poczta.o2.pl/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * O2 Plugin + * + * Imports user's contacts from O2's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class o2 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'post_login'=>'ssid', + 'url_webinterface'=>'kbshortcut', + 'url_get_webinterface'=>'kbshortcut', + 'contacts_page'=>'MSignal_UA-Download*', + 'contacts_file'=>'Title', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='o2'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://poczta.o2.pl/"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.fastmail.fm/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.fastmail.fm/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://poczta.o2.pl/login.html"; + $post_elements=array('username'=>$user,'password'=>$pass,'ssl'=>'login','x'=>rand(1,100),'y'=>rand(1,100)); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $sesid=$this->getElementString($res,'ssid=',";"); + $url_export="http://poczta.o2.pl/a?cmd=export_addressbook&requestid=2&xsfr-cookie={$sesid}&fmt=xml&upid=&"; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->post($url,array('outputformat'=>'outlook')); + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[11])) + $descriptionArray[$values[11]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>(!empty($values[3])?$values[3]:false), + 'nickname'=>(!empty($values[6])?$values[6]:false), + 'email_1'=>(!empty($values[11])?$values[11]:false), + 'email_2'=>(!empty($values[4])?$values[4]:false), + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[6])?$values[6]:false), + 'phone_home'=>(!empty($values[8])?$values[8]:false), + 'pager'=>(!empty($values[12])?$values[12]:false), + 'address_home'=>false, + 'address_city'=>false, + 'address_state'=>false, + 'address_country'=>false, + 'postcode_home'=>false, + 'company_work'=>false, + 'address_work'=>false, + 'address_work_city'=>false, + 'address_work_country'=>false, + 'address_work_state'=>false, + 'address_work_postcode'=>false, + 'fax_work'=>false, + 'phone_work'=>(!empty($values[13])?$values[13]:false), + 'website'=>(!empty($values[9])?$values[9]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url=file_get_contents($this->getLogoutPath()); + //go to url adress book url in order to make the logout + $res=$this->get($url,true); + $form_action=$this->getElementString($res,'action="','"'); + $post_elements=$this->getHiddenElements($res); + $post_elements['MSignal_AD-LGO*C-1.N-1']='Logout'; + + //get the post elements and make de logout + $res=$this->post($form_action,$post_elements,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/operamail.plg.php b/plugins/contact_importer/OpenInviter/plugins/operamail.plg.php new file mode 100755 index 00000000..dedd74d0 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/operamail.plg.php @@ -0,0 +1,180 @@ +<?php +$_pluginInfo=array( + 'name'=>'OperaMail', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from an OperaMail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.operamail.com', + 'requirement'=>'email', + 'allowed_domains'=>array('/(operamail.com)/i'), + ); +/** + * OperaMail Plugin + * + * Import user's contacts from OperaMail + * + * @author OpenInviter + * @version 1.0.4 + */ +class operamail extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $requirement='email'; + public $internalError=false; + protected $timeout=30; + public $allowed_domains=array('operamail'); + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'main?.ob', + 'file_contacts'=>'"' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='operamail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.operamail.com/scripts/common/index.main?signin=1&lang=us",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.operamail.com/scripts/common/index.main?signin=1&lang=us",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.operamail.com/scripts/common/index.main?signin=1&lang=us",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://www.operamail.com/scripts/common/proxy.main"; + $post_elements=$this->getHiddenElements($res);$post_elements['login']=$user;$post_elements['password']=$pass; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_file_contacts="http://mymail.operamail.com/scripts/addr/external.cgi?.ob=&gab=1"; + $this->login_ok=$url_file_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $form_action=$url; + $post_elements=array('showexport'=>'showexport', + 'action'=>'export', + 'login'=>$this->service_user, + 'format'=>'csv' + ); + $res=$this->post($form_action,$post_elements); + + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('file_contacts',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[1])?$values[1]:false), + 'last_name'=>(!empty($values[2])?$values[1]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>(!empty($values[12])?$values[12]:false), + 'email_3'=>(!empty($values[13])?$values[13]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[10])?$values[10]:false), + 'phone_home'=>(!empty($values[6])?$values[6]:false), + 'pager'=>(!empty($values[8])?$values[8]:false), + 'address_home'=>false, + 'address_city'=>(!empty($values[28])?$values[28]:false), + 'address_state'=>(!empty($values[29])?$values[29]:false), + 'address_country'=>(!empty($values[31])?$values[31]:false), + 'postcode_home'=>(!empty($values[30])?$values[30]:false), + 'company_work'=>(!empty($values[17])?$values[17]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[21])?$values[21]:false), + 'address_work_country'=>(!empty($values[24])?$values[24]:false), + 'address_work_state'=>(!empty($values[22])?$values[22]:false), + 'address_work_postcode'=>(!empty($values[23])?$values[23]:false), + 'fax_work'=>false, + 'phone_work'=>(!empty($values[7])?$values[7]:false), + 'website'=>false, + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $url_logout="http://mymail.operamail.com/scripts/mail/Outblaze.mail?logout=1&.noframe=1&a=1&"; + $res=$this->get($url_logout,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/orkut.plg.php b/plugins/contact_importer/OpenInviter/plugins/orkut.plg.php new file mode 100755 index 00000000..694e7ceb --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/orkut.plg.php @@ -0,0 +1,205 @@ +<?php +$_pluginInfo=array( + 'name'=>'Orkut', + 'version'=>'1.1.6', + 'description'=>"Get the contacts from an Orkut account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.orkut.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +class orkut extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + + public $debug_array=array( + 'secondary_get'=>'Email:', + 'login_post'=>'url='', + 'url_redirect'=>'mblock', + 'url_friends'=>'mblock', + 'url_send_message'=>'scrapText', + ); + + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='orkut'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://m.orkut.com/",true); + if ($this->checkResponse('secondary_get',$res)) + $this->updateDebugBuffer('secondary_get',"http://www.orkut.com/",'GET'); + else + { + $this->updateDebugBuffer('secondary_get',"http://www.orkut.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $postAction = "https://www.google.com/accounts/ServiceLoginAuth?service=orkut"; + $postElem = $this->getHiddenElements($res); + $postElem["Email"] = $user; + $postElem["Passwd"]= $pass; + $res=$this->post($postAction,$postElem,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$postAction,'POST',true,$postElem); + else + { + $this->updateDebugBuffer('login_post',$postAction,'POST',false,$postElem); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + + $url_redirect=html_entity_decode($this->getElementString($res,'url='',''')); + $res=$this->get($url_redirect,true); + + if (strpos($res,'url='')!==false) + { + $url_redirect=html_entity_decode($this->getElementString($res,'url='',''')); + $res=$this->get($url_redirect,true); + } + if ($this->checkResponse('url_redirect',$res)) + $this->updateDebugBuffer('url_redirect',"http://www.orkut.com/",'GET'); + else + { + $this->updateDebugBuffer('url_redirect',"http://www.orkut.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok = "http://m.orkut.com/Friends"; + return true; + } + + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $originalLink = array( + "a"=>"http://m.orkut.com/ShowFriends?small=a&caps=A&pgsize=10000", + "b"=>"http://m.orkut.com/ShowFriends?small=b&caps=B&pgsize=10000", + "c"=>"http://m.orkut.com/ShowFriends?small=c&caps=C&pgsize=10000", + "d"=>"http://m.orkut.com/ShowFriends?small=d&caps=D&pgsize=10000", + "e"=>"http://m.orkut.com/ShowFriends?small=e&caps=E&pgsize=10000", + "f"=>"http://m.orkut.com/ShowFriends?small=f&caps=F&pgsize=10000", + "g"=>"http://m.orkut.com/ShowFriends?small=g&caps=G&pgsize=10000", + "h"=>"http://m.orkut.com/ShowFriends?small=h&caps=H&pgsize=10000", + "i"=>"http://m.orkut.com/ShowFriends?small=i&caps=I&pgsize=10000", + "j"=>"http://m.orkut.com/ShowFriends?small=j&caps=J&pgsize=10000", + "k"=>"http://m.orkut.com/ShowFriends?small=k&caps=K&pgsize=10000", + "l"=>"http://m.orkut.com/ShowFriends?small=l&caps=L&pgsize=10000", + "m"=>"http://m.orkut.com/ShowFriends?small=m&caps=M&pgsize=10000", + "n"=>"http://m.orkut.com/ShowFriends?small=n&caps=N&pgsize=10000", + "o"=>"http://m.orkut.com/ShowFriends?small=o&caps=O&pgsize=10000", + "p"=>"http://m.orkut.com/ShowFriends?small=p&caps=P&pgsize=10000", + "q"=>"http://m.orkut.com/ShowFriends?small=q&caps=Q&pgsize=10000", + "r"=>"http://m.orkut.com/ShowFriends?small=r&caps=R&pgsize=10000", + "s"=>"http://m.orkut.com/ShowFriends?small=s&caps=S&pgsize=10000", + "t"=>"http://m.orkut.com/ShowFriends?small=t&caps=T&pgsize=10000", + "u"=>"http://m.orkut.com/ShowFriends?small=u&caps=U&pgsize=10000", + "v"=>"http://m.orkut.com/ShowFriends?small=v&caps=V&pgsize=10000", + "w"=>"http://m.orkut.com/ShowFriends?small=w&caps=W&pgsize=10000", + "x"=>"http://m.orkut.com/ShowFriends?small=x&caps=X&pgsize=10000", + "y"=>"http://m.orkut.com/ShowFriends?small=y&caps=Y&pgsize=10000", + "z"=>"http://m.orkut.com/ShowFriends?small=z&caps=Z&pgsize=10000", + "*"=>"http://m.orkut.com/ShowFriends?small=*&caps=*&pgsize=10000" + ); + + $contacts=array(); + foreach($originalLink as $link) + { + $res=$this->get($link,true); + if ($this->checkResponse('url_friends',$res)) + $this->updateDebugBuffer('url_friends',$link,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$link,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='mblock']";$data=$xpath->query($query); + foreach ($data as $node) + { + $firstChild=$node->childNodes->item(1); + if (isset($firstChild)) if ($firstChild->nodeName=='a') if (strpos((string)$firstChild->getAttribute('href'),'/FullProfile?uid=')!==false) + { + $id=str_replace('/FullProfile?uid=','',(string)$firstChild->getAttribute('href'));$name=trim(preg_replace('/[^(\x20-\x7F)]*/','',(string)$firstChild->nodeValue)); + if (!empty($id)) $contacts[$id]=$name; + } + } + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $url_scrap="http://m.orkut.com/Scrapbook?uid={$id}"; + $res=$this->get($url_scrap); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_scrap,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_scrap,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://m.orkut.com/Scrapbook"; + $post_elements=$this->getHiddenElements($res);$post_elements['scrapText']=str_replace(array('.','&'),'~',$message['body']); + $res=$this->post($form_action,$post_elements,true); + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url = "http://www.orkut.com/GLogin.aspx?cmd=logout"; + $res = $this->get($logout_url); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/perfspot.plg.php b/plugins/contact_importer/OpenInviter/plugins/perfspot.plg.php new file mode 100755 index 00000000..fde5dc93 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/perfspot.plg.php @@ -0,0 +1,209 @@ +<?php +/*Import Friends from Perfspot + * You can send private message using Perfspot system to your Friends + */ +$_pluginInfo=array( + 'name'=>'Perfspot', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a Perfspot account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://m.perfspot.com/index.asp', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Perfspot Plugin + * + * Imports user's contacts from Perfspot and send messages + * using Perfspot's internal system + * + * @author OpenInviter + * @version 1.0.6 + */ +class perfspot extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'txtEmail', + 'post_login'=>'accesskey="7"', + 'url_menu'=>'class="name"', + 'url_friend'=>'accesskey="4"', + 'url_send_message'=>'Title', + 'send_message'=>'color: Red;' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='perfspot'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://m.perfspot.com/index.asp"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://m.perfspot.com/index.asp",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://m.perfspot.com/index.asp",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://m.perfspot.com/index.asp"; + $post_elements=array('txtEmail'=>$user, + 'txtPassword'=>$pass, + 'LoginButton'=>'Login' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_menu_array=$this->getElementDOM($res,"//a[@accesskey='7']",'href'); + $url_menu="http://m.perfspot.com/".$url_menu_array[0]; + $this->login_ok=$url_menu; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + + $url_contacts_array=$this->getElementDOM($res,"//a[@accesskey='3']",'href'); + $url_contacts="http://m.perfspot.com/".$url_contacts_array[0]; + $res=$this->get($url_contacts); + if ($this->checkResponse('url_menu',$res)) + $this->updateDebugBuffer('url_menu',$url,'GET'); + else + { + $this->updateDebugBuffer('url_menu',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@class='name']";$data=$xpath->query($query); + foreach($data as $node) + $contacts[$node->getAttribute('href')]=$node->nodeValue; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_friend=html_entity_decode("http://m.perfspot.com/{$href}"); + $res=$this->get($url_friend); + if ($this->checkResponse('url_friend',$res)) + $this->updateDebugBuffer('url_friend',$url_friend,'GET'); + else + { + $this->updateDebugBuffer('url_friend',$url_friend,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_message_array=$this->getElementDOM($res,"//a[@accesskey='4']",'href'); + $url_message="http://m.perfspot.com/".$url_message_array[0]; + $res=$this->get($url_message); + if ($this->checkResponse('url_send_message',$res)) + $this->updateDebugBuffer('url_send_message',$url_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://m.perfspot.com/".$this->getElementString($res,'action="','"'); + $post_elements=array('Title'=>$message['subject'],'txtMessage'=>$message['body'],'btnSend'=>'Send'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('send_message',$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://m.perfspot.com/index.asp?mode=logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + + } + } + +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/plaxo.plg.php b/plugins/contact_importer/OpenInviter/plugins/plaxo.plg.php new file mode 100755 index 00000000..4eb891ff --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/plaxo.plg.php @@ -0,0 +1,136 @@ +<?php +$_pluginInfo=array( + 'name'=>'Plaxo', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from a plaxo account", + 'base_version'=>'1.6.3', + 'type'=>'social', + 'check_url'=>'http://m.plaxo.com', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * plaxo.com Plugin + * + * Imports user's contacts from plaxo.com's AddressBook + * + * @author OpenInviter + * @version 1.4.7 + */ +class plaxo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $debug_array=array( + 'initial_check'=>'Welcome', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user.c + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='plaxo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $postAction = "http://m.plaxo.com/index.php?page=login"; + $postElem['email']=$user; + $postElem['password']=$pass; + $res = $this->post($postAction, $postElem, true); + if ($this->checkResponse("initial_check",$res)) + $this->updateDebugBuffer('initial_check',$postAction,'POST'); + else + { + $this->updateDebugBuffer('initial_check',$postAction,'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok = "http://m.plaxo.com/?page=contacts"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + $url=$this->login_ok; + $contacts = array(); +//Thanks to ROBOV99 for the pagination code + $boolContinue = true; + $inti =1; + while($boolContinue) + { + $res=$this->get($url,true); + $res = $this->getElementString($res, "</p>", "</div>"); + $res.="//exit//"; + $iCntThisPage =0; + while(stripos($res,'<a href="') !== false) + { + $res = $this->getElementString($res, '<a href="','//exit//'); + $mail = $this->getElementString($res, '&id=','">'); + $contactstemp[$mail] = $this->getElementString($res,'">','</a>'); + if (strlen($mail) >2) $iCntThisPage++; + $res.="//exit//"; + } + if (0== $iCntThisPage) break; + $strBegin = "http://m.plaxo.com/?page=contacts&pageNum="; + $inti = $inti + 1; + $url = $strBegin.$inti; + } + if (!empty($contactstemp)) + foreach ($contactstemp as $id=>$name) + { + $res = $this->get("http://m.plaxo.com/?page=contact&id=".$id,true); + $mail = $this->getElementString($res,'mailto:','"'); + unset($contacts[$id]); + $contacts[$mail]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$mail); + } + foreach ($contacts as $email=>$name) + { if (!$this->isEmail($email)) unset($contacts[$email]); } + return $this->returnContacts($contacts); +} + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debugger. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res = $this->get('http://m.plaxo.com/index.php?page=logout', true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/plazes.plg.php b/plugins/contact_importer/OpenInviter/plugins/plazes.plg.php new file mode 100755 index 00000000..4e61d495 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/plazes.plg.php @@ -0,0 +1,186 @@ +<?php +/*Import Friends from Plazes + * You can Write Private Messages using Plazes system + */ +$_pluginInfo=array( + 'name'=>'Plazes', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Plazes account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.plazes.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Plazes Plugin + * + * Import Friends from Plazes + * You can Write Private Messages using Plazes system + * + * @author OpenInviter + * @version 1.0.0 + */ +class plazes extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'sign_out', + 'get_friends'=>'vcard', + 'send_message'=>'sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='plazes'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://plazes.com/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.plazes.com/en/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.plazes.com/en/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://plazes.com/sessions"; + $post_elements=array('return_to'=>'/', + 'login'=>$user, + 'password'=>$pass, + 'remember_me'=>1, + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://plazes.com/manage/contacts'; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $names_array=$this->getElementDOM($res,"//a[@rel='vcard']"); + $hrefs_array=$this->getElementDOM($res,"//a[@rel='vcard']",'href'); + if (!empty($hrefs_array)) + foreach($hrefs_array as $key=>$value) + { + $id=str_replace('/users/','',$value); + $contacts[$id]=(!empty($names_array[$key])?$names_array[$key]:false); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://plazes.com/messages"; + $post_elements=array('message[recipient_id]'=>$id, + 'message[body]'=>$message['body'], + 'return_to'=>"/users/{$id}" + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.plazes.com/en/logout/"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/plurk.plg.php b/plugins/contact_importer/OpenInviter/plugins/plurk.plg.php new file mode 100755 index 00000000..b0854c33 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/plurk.plg.php @@ -0,0 +1,181 @@ +<?php +$_pluginInfo=array( + 'name'=>'Plurk', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a Plurk account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.plurk.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Plurk Plugin + * + * Imports user's contacts from Plurk and + * . + * + * @author OpenInviter + * @version 1.0.3 + */ +class plurk extends openinviter_base + { + private $login_ok=false; + public $showContacts=false; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'nick_name', + 'login'=>'user_id', + 'get_contacts'=>'nick_name', + 'send_message'=>'"error": null' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='plurk'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.plurk.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.plurk.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.plurk.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.plurk.com/Users/login'; + $post_elements=array('nick_name'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login",$res)) + $this->updateDebugBuffer('login',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $user_id=$this->getElementString($res,'"user_id": ',','); + $this->login_ok=$is->login_ok=$user_id; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $user_id=$this->login_ok; + $url_request_friends="http://www.plurk.com/Friends/getFriendsByOffset"; + $post_elements=array('offset'=>0,'user_id'=>$user_id); + $res=$this->post($url_request_friends,$post_elements,true); + if ($this->checkResponse("get_contacts",$res)) + $this->updateDebugBuffer('get_contacts',$url_request_friends,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('get_contacts',$url_request_friends,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + while(strpos($res,'"nick_name": "')!==false) + { + $name=$this->getElementString($res,'"nick_name": "','"'); + $name_delete='"nick_name": "'.$name; + $uid=$this->getElementString($res,'"uid": ',','); + $uid_delete='"uid": '.$uid; + $res=str_replace($name_delete,'',str_replace($uid_delete,'',$res)); + if(isset($uid)) $contacts[$uid]=(isset($name)?$name:false); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $res=$this->get('http://www.plurk.com',true); + $user_id=$this->getElementString($res,'"user_id": ',','); + $form_action="http://www.plurk.com/TimeLine/addPlurk"; + $post_elements=array('posted'=>'%222009-1-12T14%3A18%3A30%22', + 'qualifier'=>'is', + 'content'=>$message['body'], + 'lang'=>'en', + 'no_comments'=>0, + 'uid'=>$user_id + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.plurk.com/Users/logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/pochta.plg.php b/plugins/contact_importer/OpenInviter/plugins/pochta.plg.php new file mode 100755 index 00000000..cd3d2b7e --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/pochta.plg.php @@ -0,0 +1,170 @@ +<?php +$_pluginInfo=array( + 'name'=>'Pochta', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Pochta account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.pochta.ru/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Pochta Plugin + * + * Imports user's contacts from Pochta AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class pochta extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'user', + 'login_post'=>'inbox', + 'url_export'=>',"', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='pochta'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.pochta.ru/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.pochta.ru/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.pochta.ru/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $user_array=explode('@',$user);$username=$user_array[0];$domain=$user_array[1]; + $form_action="http://www.pochta.ru/auth/logon"; + $post_elements=array('reason'=>'login','back'=>false,'lng'=>'ru','user'=>$username,'domain'=>$domain,'pass'=>$pass,'long_session'=>1); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok="http://www.pochta.ru/adb/export/?export_type=outlook&export_action=export"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_export",$res)) + $this->updateDebugBuffer('url_export',$url,'GET'); + else + { + $this->updateDebugBuffer('url_export',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $temp=$this->parseCSV($res);$teM=explode(PHP_EOL,$res);$arrayDescriptionFlag=explode(',',$teM[0]);print_R($arrayDescriptionFlag); + foreach ($temp as $values) + { + if (!empty($values[82])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[1])?$values[1]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>false, + 'nickname'=>false, + 'email_1'=>(!empty($values[82])?$values[82]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://www.pochta.ru/auth/logout/',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/popstarmail.plg.php b/plugins/contact_importer/OpenInviter/plugins/popstarmail.plg.php new file mode 100755 index 00000000..10ae8891 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/popstarmail.plg.php @@ -0,0 +1,182 @@ +<?php +$_pluginInfo=array( + 'name'=>'Popstarmail', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from an Popstarmail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://super.popstarmail.org/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * popstarmail Plugin + * + * Imports user's contacts from popstarmail's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class popstarmail extends openinviter_base +{ + private $login_ok=false; + protected $timeout=30; + public $showContacts=true; + public $debug_array=array( + 'initial_get'=>'show_frame', + 'login_post'=>'ob', + 'get_contacts'=>'showexport', + 'contacts_file'=>'Name' + ); + +/** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='popstarmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://super.popstarmail.org/",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://super.popstarmail.org/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://super.popstarmail.org/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://super.popstarmail.org/scripts/common/ss_main.cgi"; + $post_elements=array('show_frame'=>'Enter','action'=>'login','login'=>$user,'password'=>$pass,'x'=>rand(5,15),'y'=>rand(5,15)); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $sid=$this->getElementString($res,'ob=','"'); + $url_export="http://mymail.hk.popstarmail.org/scripts/addr/external.cgi?.ob={$sid}&gab=1"; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('get_contacts',$res)) + $this->updateDebugBuffer('get_contacts',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET'); + else + { + $this->updateDebugBuffer('get_contacts',"http://www.evite.com/loginRegForm?redirect=/pages/addrbook/contactList.jsp",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action=$url; + $post_elements=array('showexport'=>'showexport','action'=>'export','login'=>$this->service_user,'format'=>'csv'); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('contacts_file',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[4])) + $contacts[$values[4]]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>false, + 'email_1'=>(!empty($values[4])?$values[4]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url="http://mymail.hk.popstarmail.org/scripts/mail/Outblaze.mail?logout=1&.noframe=1&a=1&"; + $res = $this->get($logout_url,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/rambler.plg.php b/plugins/contact_importer/OpenInviter/plugins/rambler.plg.php new file mode 100755 index 00000000..e87c2e03 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/rambler.plg.php @@ -0,0 +1,142 @@ +<?php +$_pluginInfo=array( + 'name'=>'Rambler', + 'version'=>'1.1.4', + 'description'=>"Get the contacts from a Rambler account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.rambler.ru', + 'requirement'=>'email', + 'allowed_domains'=>array('/(rambler.ru)/i'), + ); +/** + * Rambler Plugin + * + * Import user's contacts from Rambler AddressBook + * + * @author OpenInviter + * @version 1.0.9 + */ +class rambler extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'login', + 'login_post'=>'ramac_add_handler', + 'url_contacts'=>'mode=compose' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='rambler'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.rambler.ru/",true); + + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.rambler.ru/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.rambler.ru/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $post_elements=$this->getHiddenElements($res);$post_elements['login']=$user;$post_elements['passw']=$pass; + unset($post_elements[0]); + $res=$this->post("http://id.rambler.ru/script/auth.cgi",$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"http://id.rambler.ru/script/auth.cgi",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"http://id.rambler.ru/script/auth.cgi",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contact_array=$this->getElementDOM($res,"//a[@id='addressbook-link']",'href'); + $value=substr($url_contact_array[0],strpos($url_contact_array[0],"r=")+2,strlen($url_contact_array[0])-strpos($url_contact_array[0],"r=")-2); + $url_contact="http://mail.rambler.ru/mail/contacts.cgi?r={$value}"; + $this->login_ok=$url_contact; + file_put_contents($this->getLogoutPath(),$value); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $emailsArray=$this->getElementDOM($res,"//a[@class='email']"); + $namesArray=$this->getElementDOM($res,"//td[@class='org ']"); + if (!empty($emailsArray)) + foreach($emailsArray as $key=>$emailValue) $contacts[$emailValue]=array('first_name'=>(isset($namesArray[$key])?$namesArray[$key]:false),'email_1'=>$emailValue); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout="http://id.rambler.ru/script/auth.cgi?back=;mode=logout;r=".file_get_contents($this->getLogoutPath()); + $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/rediff.plg.php b/plugins/contact_importer/OpenInviter/plugins/rediff.plg.php new file mode 100755 index 00000000..0c9ee42d --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/rediff.plg.php @@ -0,0 +1,161 @@ +<?php +$_pluginInfo=array( + 'name'=>'Rediff', + 'version'=>'1.2.0', + 'description'=>"Get the contacts from a Rediff account", + 'base_version'=>'1.8.1', + 'type'=>'email', + 'check_url'=>'http://mail.rediff.com', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Rediff Plugin + * + * Import user's contacts from Rediff's AddressBook + * + * @author OpenInviter + * @version 1.1.6 + */ +class rediff extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + private $sess_id, $username, $siteAddr; + public $debug_array=array( + 'login_post'=>'window.location.replace', + 'url_contacts'=>'var session_id', + 'url_contacts_form'=>'els', + 'file_contacts'=>'Name', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='rediff'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $post_elements=array("login"=>"{$user}", + "passwd"=>"{$pass}", + "FormName"=>"existing"); + $res=htmlentities($this->post("http://mail.rediff.com/cgi-bin/login.cgi",$post_elements,true)); + if ($this->checkResponse("login_post",$res)) + { + $this->updateDebugBuffer('login_post',"http://mail.rediff.com/cgi-bin/login.cgi",'POST',true,$post_elements); + $link_to_extract = $this->getElementString($res, 'window.location.replace("', '");'); + $this->siteAddr = $this->getElementString($link_to_extract,'http://','/'); + $this->username = $user; + $this->sess_id = $this->getElementString($link_to_extract,'&session_id=','&'); + $url_redirect = "http://{$this->siteAddr}/bn/toggle.cgi?flipval=1&login={$this->username}&session_id={$this->sess_id}&folder=Inbox&formname=sh_folder&user_size=1"; + } + else + { + $this->updateDebugBuffer('login_post',"http://mail.rediff.com/cgi-bin/login.cgi",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $res = ($this->get($url_redirect, true)); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('url_contacts',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_contact="http://{$this->siteAddr}/prism/exportaddrbook?output=web"; + $this->login_ok = $url_contact; + $logout_url = "http://login.rediff.com/bn/logout.cgi?formname=general&login={$this->username}&session_id={$this->sess_id}&function_name=logout"; + file_put_contents($this->getLogoutPath(),$logout_url); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_contacts_form",$res)) + $this->updateDebugBuffer('url_contacts_form',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts_form',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=array('output'=>'web','els'=>$this->getElementString($res,'name="els" value="','"'),'exporttype'=>'outlook'); + $form_action="http://{$this->siteAddr}/prism/exportaddrbook?service=outlook"; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("file_contacts",$res)) + $this->updateDebugBuffer('file_contacts',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('file_contacts',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + $name=$values['0'].(empty($values['1'])?'':(empty($values['0'])?'':'-')."{$values['1']}").(empty($values['3'])?'':" \"{$values['3']}\"").(empty($values['2'])?'':' '.$values['2']); + if (!empty($values['5'])) + $contacts[$values['5']]=array('first_name'=>$name,'email_1'=>$values['5']); + } + + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout=file_get_contents($this->getLogoutPath()); + if (!empty($url_logout)) $res=$this->get($url_logout); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/sapo.plg.php b/plugins/contact_importer/OpenInviter/plugins/sapo.plg.php new file mode 100755 index 00000000..a7bce3de --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/sapo.plg.php @@ -0,0 +1,129 @@ +<?php +/*This plugin import Sapo contacts + *You can send normal email + */ +$_pluginInfo=array( + 'name'=>'Sapo.pt', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Sapo.pt account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://services.mail.sapo.pt/codebits/', + 'requirement'=>'email', + 'allowed_domains'=>array('/(sapo.pt)/i'), + ); +/** + * Sapo Plugin + * + * Imports user's contacts from Sapo.pt's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class sapo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'username', + 'get_contacts'=>'email', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='sapo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://services.mail.sapo.pt/codebits/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://services.mail.sapo.pt/codebits/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://services.mail.sapo.pt/codebits/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok=array('user'=>$user,'pass'=>$pass); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $data=$this->login_ok; + + $form_action="http://services.mail.sapo.pt/codebits/index.php"; + $post_elements=array('username'=>$data['user'],'password'=>$data['pass'],'what'=>'contactos'); + + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("get_contacts",$res)) + $this->updateDebugBuffer('get_contacts',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('get_contacts',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $name_array=$this->getElementDOM($res,"//span[@class='n fn']"); + $niks_array=$this->getElementDOM($res,"//span[@class='nickname']"); + $email_array=$this->getElementDOM($res,"//span[@class='email']"); + foreach($name_array as $key=>$value) + $contacts[$email_array[$key]]=array('first_name'=>$value,'nickname'=>(isset($niks_array[$key])?$niks_array[$key]:false),'email_1'=>$email_array[$key]); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/skyrock.plg.php b/plugins/contact_importer/OpenInviter/plugins/skyrock.plg.php new file mode 100755 index 00000000..93c19318 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/skyrock.plg.php @@ -0,0 +1,206 @@ +<?php +/*Import Friends from Skyrock + * You can send private message using Skyrock system to your Friends + */ +$_pluginInfo=array( + 'name'=>'Skyrock', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from a Skyrock account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.skyrock.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Skyrock Plugin + * + * Imports user's contacts from Skyrock and send messages + * using Skyrock's internal system + * + * @author OpenInviter + * @version 1.0.0 + */ +class skyrock extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'need_login_form_login', + 'login_post'=>'logout', + 'url_friends'=>'class="ecrire"', + 'url_send_message'=>'id_dest', + 'send_message'=>'confirmation' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='skyrock'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.skyrock.com"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.skyrock.com",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.skyrock.com",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.skyrock.com/"; + $post_elements=array('need_login_form_login'=>$user, + 'need_login_form_password'=>$pass, + 'x'=>rand(0,20), + 'y'=>rand(0,20), + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends="http://www.skyrock.com/m/friends/"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_friends",$res)) + $this->updateDebugBuffer('url_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('url_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $page=0;$hasFriends=true; + while($hasFriends) + { + $page++;$message_array=array(); + $names_array=$this->getElementDOM($res,"//ul[@class='friends_list']/li",'title'); + $message_array=$this->getElementDOM($res,"//a[@class='ecrire']",'href'); + if (empty($message_array)) $hasFriends=false; + if (!empty($names_array)) foreach($names_array as $key=>$value) $contacts[$message_array[$key]]=$value; + $url_next="http://www.skyrock.com/m/friends/?order=1&page={$page}"; + $res=$this->get($url_next,true); + } + + return $contacts; + } + + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $session_id The OpenInviter user's session ID + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message=html_entity_decode("http://www.skyrock.com{$href}"); + $res=$this->get($url_send_message); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.skyrock.com/m/messages/write_message.php"; + $post_elements=array('id_dest'=>$this->getElementString($res,'name="id_dest" value="','"'), + 'sendMe'=>$this->getElementString($res,'sendMe" value="','"'), + 'posted'=>TRUE, + 'message_zone'=>$message['body'], + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.skyrock.com/m/account/logout.php"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + + } + } + +?> diff --git a/plugins/contact_importer/OpenInviter/plugins/tagged.plg.php b/plugins/contact_importer/OpenInviter/plugins/tagged.plg.php new file mode 100755 index 00000000..da591c72 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/tagged.plg.php @@ -0,0 +1,192 @@ +<?php +$_pluginInfo=array( + 'name'=>'Tagged', + 'version'=>'1.0.9', + 'description'=>"Get the contacts from a Tagged.com account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.tagged.com/home.html', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Tagged Plugin + * + * Import user's contacts from a Tagged Account + * + * @author OpenInviter + * @version 1.0.0 + */ +class tagged extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + + public $debug_array=array( + 'login_post'=>'http://www.tagged.com/home.html?jli=1', + 'redirect'=>'http://www.tagged.com/logout.html', + 'contacts'=>'name', + 'message'=>'recipientId' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='tagged'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res = $this->get("http://www.tagged.com"); + $postAction = "https://secure.tagged.com/secure_login.html?r=%2Fhome.html&uri=http%3A%2F%2Fwww.tagged.com"; + $postElem = array(); + $postElem['username'] = $user; + $postElem['password'] = $pass; + $res = $this->post($postAction, $postElem, true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$postAction,'POST',true,$postElem); + else + { + $this->updateDebugBuffer('login_post',$postAction,'POST',false,$postElem); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $res = $this->get("http://www.tagged.com/home.html?jli=1"); + if ($this->checkResponse("redirect",$res)) + $this->updateDebugBuffer('redirect',"http://www.tagged.com/home.html?jli=1",'GET'); + else + { + $this->updateDebugBuffer('redirect',"http://www.tagged.com/home.html?jli=1",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_get_friends='http://www.tagged.com/messages.html?action=compose'; + $this->login_ok=$url_get_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("contacts",$res)) + $this->updateDebugBuffer('contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts = array(); + if (preg_match_all("#\{\"name\"\:\"(.+)\"\,\"id\"\:(.+)\}#U", $res, $matches)) + { + if (!empty($matches[1])) + foreach($matches[1] as $key=>$value) + if (!empty($matches[2][$key])) $contacts[$matches[2][$key]]=$value; + } + + reset($contacts);$firstKey=key($contacts); + if (preg_match("#\[\{\"name\"\:\"(.+)\"\,\"id\"\:(.+)\}#U", $res, $matches)) $contacts[$firstKey]=$matches[1]; + else unset($contacts[$firstKey]); + + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach ($contacts as $id=>$username) + { + $countMessages++; + $form_action='http://www.tagged.com/handle_inbox.html'; + $post_elements=array('recipient_id'=>$id, + 'subject'=>$message['subject'], + 'mce_editor_0_fontSizeSelect'=>0, + 'entryText'=>$message['body'], + 'from'=>'compose', + 'section'=>'send', + 'message_type'=>'N', + 'came_from_url'=>'http://www.tagged.com/messages.html', + 'save_sent'=>'save', + 'action'=>'sendMessage', + 'skip_confirmation'=>1, + 'ajax_sent'=>1, + 'recipient_id_hidden'=>0, + 'on_success_action'=>'call_function|complete_sendMsg()' + ); + $res=$this->post($form_action,$post_elements,true); + if (strpos($res,'captcha')) break; + if ($this->checkResponse("message",$res)) + $this->updateDebugBuffer('message',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('message',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url = "http://www.tagged.com/logout.html"; + $res = $this->get($logout_url); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/techemail.plg.php b/plugins/contact_importer/OpenInviter/plugins/techemail.plg.php new file mode 100755 index 00000000..3b391946 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/techemail.plg.php @@ -0,0 +1,142 @@ +<?php +$_pluginInfo=array( + 'name'=>'Techemail', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from an Techemail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://techemail.mail.everyone.net/email/scripts/loginuser.pl', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Techemail Plugin + * + * Imports user's contacts from Techemail's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class techemail extends openinviter_base +{ + private $login_ok=false; + protected $timeout=30; + public $showContacts=true; + public $debug_array=array( + 'initial_get'=>'loginName', + 'login_post'=>'oi_sda_firstname', + 'get_contacts'=>'composeMe', + ); + +/** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='techemail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("http://techemail.mail.everyone.net/email/scripts/loginuser.pl",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://super.popstarmail.org/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://super.popstarmail.org/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://techemail.mail.everyone.net/email/scripts/loginuser.pl?EV1=".$this->getElementString($res,"loginuser.pl?EV1=",'"'); + $post_elements=array('loginName'=>$user,'user_pwd'=>$pass,'login'=>'Login'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_contacts="http://techemail.mail.everyone.net/email/scripts/contacts.pl?EV1="; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse('get_contacts',$res)) + $this->updateDebugBuffer('get_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('get_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + { + $nameBulk=$node->getAttribute('href'); + if (strpos($nameBulk,'javascript:composeMe')!==false) + { + $name=$this->getElementString($nameBulk,'"','"');$email=$node->nodeValue; + if (!empty($email)) $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $logout_url="http://techemail.mail.everyone.net/email/scripts/logout.pl"; + $res = $this->get($logout_url,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/terra.plg.php b/plugins/contact_importer/OpenInviter/plugins/terra.plg.php new file mode 100755 index 00000000..940036b1 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/terra.plg.php @@ -0,0 +1,148 @@ +<?php +$_pluginInfo=array( + 'name'=>'Terra', + 'version'=>'1.0.7', + 'description'=>"Get the contacts from an Terra account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://correo.terra.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Terra Plugin + * + * Imports user's contacts from Terra.com + * + * @author OpenInviter + * @version 1.0.0 + */ +class terra extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'username', + 'post_login'=>'location.href', + 'url_post_redirect'=>'td', + 'file_contacts'=>'Users["' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='terra'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://correo.terra.com/"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://correo.terra.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://correo.terra.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://correo.terra.com/atmail.php"; + $post_elements=array('username'=>$user,'password'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_redirect=$this->getElementString($res,"href='","'"); + $domain=$this->getElementString($res,'http://correo.terra.com/','/showmail'); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('url_post_redirect',$res)) + $this->updateDebugBuffer('url_post_redirect',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('url_post_redirect',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_file_contacts="http://correo.terra.com/{$domain}/abook.php?func=composebook&emailto=&emailcc=&emailbcc="; + $this->login_ok=$url_file_contacts; + file_put_contents($this->getLogoutPath(),$domain); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse('file_contacts',$res)) + $this->updateDebugBuffer('file_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('file_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + if (preg_match_all("#Users\[\"(.+)\"\] \= \'(.+) \<\;#U", $res, $matches)) + if (!empty($matches[1])) + foreach($matches[1] as $key=>$email) + $contacts[$email]=array('first_name'=>(!empty($matches[2][$key])?$matches[2][$key]:false),'email_1'=>$email); + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { $domain=file_get_contents($this->getLogoutPath());$res=$this->get("http://correo.terra.com{$domain}/index.php?func=logout",true); } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/twitter_ex.plg.php b/plugins/contact_importer/OpenInviter/plugins/twitter_ex.plg.php new file mode 100755 index 00000000..cb971299 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/twitter_ex.plg.php @@ -0,0 +1,160 @@ +<?php +$_pluginInfo=array( + 'name'=>'Twitter', + 'version'=>'1.0.8', + 'description'=>"Get the contacts from a Twitter account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://twitter.com', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Twitter Plugin + * + * Imports user's contacts from Twitter and + * posts a new tweet from the user as a invite. + * + * @author OpenInviter + * @version 1.0.3 + */ +class twitter_ex extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'responce_ok'=>'screen_name', + 'responce_ok_followers'=>'screen_name', + 'responce_ok_status'=>'status', + 'url_direct_message'=>'direct_message' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='twitter'; + $this->service_user=$user; + $this->service_pass=$pass; + if (!$this->init()) return false; + $res=$this->get("http://{$user}:{$pass}@twitter.com/account/verify_credentials.xml",true); + if ($this->checkResponse('responce_ok',$res)) + $this->updateDebugBuffer('responce_ok',"http://user:pass@twitter.com/account/verify_credentials.xml",'GET'); + else + { + $this->updateDebugBuffer('responce_ok',"http://user:pass@twitter.com/account/verify_credentials.xml",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + file_put_contents($this->getLogoutPath(),"{$user}/{$pass}"); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (file_exists($this->getLogoutPath())) + {$auth=explode("/",file_get_contents($this->getLogoutPath()));$user=$auth[0];$pass=$auth[1];} + else return false; + $res=$this->get("http://{$user}:{$pass}@twitter.com/statuses/followers.xml",true); + if ($this->checkResponse('responce_ok_followers',$res)) + $this->updateDebugBuffer('responce_ok_followers',"http://user:pass@twitter.com/statuses/followers.xml",'GET'); + else + { + $this->updateDebugBuffer('responce_ok_followers',"http://user:pass@twitter.com/statuses/followers.xml",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=$this->getElementDOM($res,'//screen_name'); + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + if (file_exists($this->getLogoutPath())) + {$auth=explode("/",file_get_contents($this->getLogoutPath()));$user=$auth[0];$pass=$auth[1];} + else return false; + $post_elements=array('status'=>$message['body']); + $res=$this->post("http://{$user}:{$pass}@twitter.com/statuses/update.xml",$post_elements,true); + if ($this->checkResponse('responce_ok_status',$res)) + $this->updateDebugBuffer('responce_ok_status',"http://user:pass@twitter.com/statuses/update.xml",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('responce_ok_status',"http://user:pass@twitter.com/statuses/update.xml",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $countMessages=0; + foreach($contacts as $key=>$screen_name) + { + $countMessages++; + $post_elements=array('user'=>$screen_name,'text'=>$message['body']); + $res=$this->post("http://{$user}:{$pass}@twitter.com/direct_messages/new.xml",$post_elements); + if ($this->checkResponse('url_direct_message',$res)) + $this->updateDebugBuffer('url_direct_message',"http://user:pass@twitter.com/direct_messages/new.xml",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('url_direct_message',"http://user:pass@twitter.com/direct_messages/new.xml",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + * + */ + public function logout() + { + if (!$this->checkSession()) return false; + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/uk2.plg.php b/plugins/contact_importer/OpenInviter/plugins/uk2.plg.php new file mode 100755 index 00000000..24fe6cf3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/uk2.plg.php @@ -0,0 +1,185 @@ +<?php +$_pluginInfo=array( + 'name'=>'Uk2', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a Uk2 account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://mail.uk2.net/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Uk2 Plugin + * + * Imports user's contacts from Uk2 AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class uk2 extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'username', + 'login_post'=>'parse', + 'url_inbox'=>'parse', + 'contacts_file'=>'Email' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='uk2'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://mail.uk2.net/",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://mail.uk2.net/",'GET'); + else + { + $this->updateDebugBuffer('initial_get','http://mail.uk2.net/','GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://mail.uk2.net/atmail.pl'; + $post_elements=array('Language'=>'english','username'=>$user,'pop3host'=>'uk2.net','password'=>$pass,'LoginType'=>'xul'); + $res=$this->post($form_action,$post_elements,false,true,false,array(),false,false); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect='http://mail.uk2.net/'.$this->getElementString($res,"href='","'"); + $res=$this->get($url_redirect,true); + if ($this->checkResponse("url_inbox",$res)) + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET'); + else + { + $this->updateDebugBuffer('url_inbox',$url_redirect,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_export='http://mail.uk2.net/abook.pl?func=export&abookview=personal'; + $this->login_ok=$url_export; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("contacts_file",$res)) + $this->updateDebugBuffer('contacts_file',$url,'GET'); + else + { + $this->updateDebugBuffer('contacts_file',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $temp=$this->parseCSV($res); + $contacts=array(); + foreach ($temp as $values) + { + if (!empty($values[3])) + $contacts[$values[3]]=array('first_name'=>(!empty($values[20])?$values[20]:false), + 'middle_name'=>(!empty($values[8])?$values[8]:false), + 'last_name'=>false, + 'nickname'=>false, + 'email_1'=>(!empty($values[3])?$values[3]:false), + 'email_2'=>false, + 'email_3'=>false, + 'organization'=>false, + 'phone_mobile'=>(!empty($values[11])?$values[11]:false), + 'phone_home'=>(!empty($values[9])?$values[9]:false), + 'pager'=>false, + 'address_home'=>false, + 'address_city'=>(!empty($values[5])?$values[5]:false), + 'address_state'=>(!empty($values[7])?$values[7]:false), + 'address_country'=>(!empty($values[8])?$values[8]:false), + 'postcode_home'=>(!empty($values[6])?$values[6]:false), + 'company_work'=>(!empty($values[14])?$values[14]:false), + 'address_work'=>false, + 'address_work_city'=>(!empty($values[16])?$values[16]:false), + 'address_work_country'=>(!empty($values[19])?$values[19]:false), + 'address_work_state'=>(!empty($values[17])?$values[17]:false), + 'address_work_postcode'=>(!empty($values[18])?$values[18]:false), + 'fax_work'=>(!empty($values[21])?$values[21]:false), + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[12])?$values[12]:false), + 'isq_messenger'=>false, + 'skype_essenger'=>false, + 'yahoo_essenger'=>false, + 'msn_messenger'=>false, + 'aol_messenger'=>false, + 'other_messenger'=>false, + ); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://mail.uk2.net/util.pl?func=logout',true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/vimeo.plg.php b/plugins/contact_importer/OpenInviter/plugins/vimeo.plg.php new file mode 100755 index 00000000..ee3ca60d --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/vimeo.plg.php @@ -0,0 +1,195 @@ +<?php +/*Import Friends from Vimeo + * You can Post Messages using Vimeo system + */ +$_pluginInfo=array( + 'name'=>'Vimeo', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Vimeo account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://vimeo.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Vimeo Plugin + * + * Import user's contacts from Vimeo and Post comments + * using Vimeo's internal Posting system + * + * @author OpenInviter + * @version 1.0.0 + */ +class vimeo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'sign_in[email]', + 'login_post'=>'user', + 'url_home'=>'contacts', + 'get_friends'=>'username', + 'url_send_message'=>'MemoContent', + 'send_message'=>'was sent' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='vimeo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://vimeo.com/log_in"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://vimeo.com/log_in",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://vimeo.com/log_in",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://vimeo.com/log_in"; + $post_elements=array('sign_in[email]'=>$user,'sign_in[password]'=>$pass); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_profile='http://vimeo.com/'; + $this->login_ok=$url_profile; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_home",$res)) + $this->updateDebugBuffer('url_home',$url,'GET'); + else + { + $this->updateDebugBuffer('url_home',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $user_id=$this->getElementString($res,'http://vimeo.com/user','/'); + $url_contacts="http://vimeo.com/user{$user_id}/contacts"; + $res=$this->get($url_contacts); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url_contacts,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url_contacts,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@class='username']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->nodeValue; + $id=str_replace('/user','',(string)$node->getAttribute('href')); + if (!empty($name)) $contacts[$id]=$name; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $form_action="http://vimeo.com/ajax/conversation/send_message"; + $post_elements=array('message'=>$message['body'],'jdata'=>'{"user_id":'.$id.',"layout":"private"}'); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://vimeo.com/log_out"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/virgilio.plg.php b/plugins/contact_importer/OpenInviter/plugins/virgilio.plg.php new file mode 100755 index 00000000..9017f2a5 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/virgilio.plg.php @@ -0,0 +1,140 @@ +<?php +$_pluginInfo=array( + 'name'=>'Virgilio', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from an virgilio.it account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://mobimail.virgilio.it/cp/ps/Main/login/LoginVirgilio?d=virgilio.it', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Virgilio.it Plugin + * + * Imports user's contacts from Virgilio.it account + * + * @author OpenInviter + * @version 1.0.0 + */ +class virgilio extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + private $sessionVer; + public $debug_array=array('initial_get'=>'login_type', + 'login_post'=>'&t=', + 'url_contact'=>'contatti' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='virgilio'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res = $this->get("http://mobimail.virgilio.it/cp/ps/Main/login/LoginVirgilio?d=virgilio.it",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://mobimail.virgilio.it/cp/ps/Main/login/LoginVirgilio?d=virgilio.it",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://mobimail.virgilio.it/cp/ps/Main/login/LoginVirgilio?d=virgilio.it",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="http://mobimail.virgilio.it/cp/ps/Main/login/WrapLogin"; + $post_elements=array('p'=>false,'login_type'=>'virgilio','NGUserID'=>'null','u'=>$user,'password'=>$pass,'d'=>'virgilio.it'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $vergilioT=$this->getElementString($res,'&t=','&');$this->sessionVer=$vergilioT; + $url_contacts="http://mobimail.virgilio.it/cp/ps/PSPab/Contacts?d=virgilio.it&u={$user}&t={$vergilioT}&reset=true&startAt=1&l=it"; + $this->login_ok=$url_contacts; + file_put_contents($this->getLogoutPath(),$vergilioT); + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + if ($this->checkResponse("url_contact",$res)) + $this->updateDebugBuffer('url_contact',$this->login_ok,'GET'); + else + { + $this->updateDebugBuffer('url_contact',$this->login_ok,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $nrFriends=(int)$this->getElementString($res,"Hai "," contatti");$exit=0;$page=1; + while($nrFriends>count($contacts)) + { + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + if (strpos($node->getAttribute('href'),'PABreturnURL=Contacts')!==false) + { $name=$node->childNodes->item(0)->nodeValue;$email=$node->childNodes->item(2)->nodeValue;if (!empty($email)) $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); } + $page++;$res=$this->get("http://mobimail.virgilio.it/cp/ps/PSPab/Contacts?d=virgilio.it&u={$this->service_user}&t={$this->sessionVer}&reset=true&startAt={$page}&l=it",true); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + {$vergilioT=file_get_contents($this->getLogoutPath());$res=$this->get("http://mobimail.virgilio.it/cp/ps/Main/login/Logout?d=virgilio.it&u={$this->service_user}&t={$vergilioT}&l=it",true);} + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/vkontakte.plg.php b/plugins/contact_importer/OpenInviter/plugins/vkontakte.plg.php new file mode 100755 index 00000000..0d7356ea --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/vkontakte.plg.php @@ -0,0 +1,195 @@ +<?php +/*Import Friends from vkontakte.ru + * You can Post Messages using Vkontakte system + */ +$_pluginInfo=array( + 'name'=>'Vkontakte', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Vkontakte.ru account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://vkontakte.ru', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Cyworld Plugin + * + * Import user's contacts from vkontakte.ru and Sends private messages + * using vkontakte.ru internal Posting system + * + * @author OpenInviter + * @version 1.0.0 + */ +class vkontakte extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'email', + 'login_post'=>'myfriends', + 'get_friends'=>'friendOrder', + 'url_send_message'=>'title', + 'send_message'=>'<div id="message">' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='vkontakte'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://vkontakte.ru/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://vkontakte.ru/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://vkontakte.ru/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://vkontakte.ru/login.php"; + $post_elements=array("try_to_login"=>1,"email"=>$user,"pass"=>$pass); + $res=$this->post($form_action,$post_elements,true); + + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_friends="http://vkontakte.ru/".$this->getElementString($res,"myfriends'><a href='","'"); + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + while (strpos($res,'list:[[')!==false) + { + $countact_bulk=$this->getElementString($res,'list:[[','}'); + $id=substr($countact_bulk,0,strpos($countact_bulk,',')); + $names_array=explode("'",$countact_bulk); + if (isset($id)) + $contacts[$id]=(isset($names_array[1])?$names_array[1]:false)." ".(isset($names_array[3])?$names_array[3]:false); + $res=str_replace("list:[[".$countact_bulk,"",$res); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $id=>$name) + { + $countMessages++; + $url_send_message="http://vkontakte.ru/mail.php?act=write&to={$id}"; + $res=$this->get($url_send_message); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://vkontakte.ru/mail.php"; + $post_elements=$this->getHiddenElements($res);$post_elements['title']=$message['subject'];$post_elements['message']=$message['body']; + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://vkontakte.ru/login.php?op=logout"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/walla.plg.php b/plugins/contact_importer/OpenInviter/plugins/walla.plg.php new file mode 100755 index 00000000..a48393c3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/walla.plg.php @@ -0,0 +1,147 @@ +<?php +$_pluginInfo=array( + 'name'=>'Walla', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from a Walla mail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://friends.walla.co.il/?tsscript=login&theme=&ReturnURL=http://mail.walla.co.il/index.cgi', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Walla Plugin + * + * Imports user's contacts from Walla's AddressBook + * + * @author OpenInviter + * @version 1.0.0 + */ +class walla extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'@login', + 'post_login'=>'newaddress', + 'url_contacts'=>'@compose', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='walla'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://friends.walla.co.il/?tsscript=login&theme=&ReturnURL=http://mail.walla.co.il/index.cgi",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.gawab.com/default.php",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.gawab.com/default.php",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://friends.walla.co.il/"; + $post_elements=array('w'=>'/@login.commit', + 'ReturnURL'=>'http://mail.walla.co.il/index.cgi', + 'username'=>$user, + 'password'=>$pass + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('post_login',$res)) + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_contacts="http://newaddress.walla.co.il"; + $this->login_ok=$url_contacts; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse('url_contacts',$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + { + if (strpos($node->getAttribute('href'),'@view')!==false) $name=$node->nodeValue; + if (strpos($node->getAttribute('href'),'w=/@compose')!==false) $email=$node->nodeValue; + if (!empty($email)) + $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://friends.walla.co.il/?w=/@logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/web_de.plg.php b/plugins/contact_importer/OpenInviter/plugins/web_de.plg.php new file mode 100755 index 00000000..fdbcb810 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/web_de.plg.php @@ -0,0 +1,136 @@ +<?php +$_pluginInfo=array( + 'name'=>'Web.de', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from an web.de account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://m.web.de', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * web.de Plugin + * + * Imports user's contacts from web.de's AddressBook + * + * @author OpenInviter + * @version 1.6.7 + */ +class web_de extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'initial_check'=>'[5]', + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='web_de'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://m.web.de"); + $postElem = $this->getHiddenElements($res); + $postAction = $this->getElementString($res,'action="','"'); + $s=str_replace(";",'',$this->getElementString($res,'/;s=','/')); + + $postAction='/;e=utf-8;s='.$s.'/mail'; + + $postElem['user']=$user; + $postElem['passw']=$pass; + $postElem['sv-remove-name']='Login'; + $res = $this->post("http://m.web.de".$postAction, $postElem, true); + + if ($this->checkResponse("initial_check",$res)) + $this->updateDebugBuffer('initial_check',"http://m.web.de".$postAction,'POST'); + else + { + $this->updateDebugBuffer('initial_check',"http://m.web.de".$postAction,'POST',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_email=$this->getElementString($res,'[5] <a href="','"'); + + $this->login_ok =$url_email; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + $url=$this->login_ok; + //go to url inbox + $contacts = array(); + $res=$this->get($url,true); + $res = $this->getElementString($res, '</div><div class="separator">','<input type="hidden"'); + $contacts_array=$this->getElementDOM($res,'//a'); + if(!is_array($contacts_array)) + return false; + foreach($contacts_array as $key=>$val) + { + if ($key%2==0) $name=$val; + elseif($key%2!=0) + { + $val = preg_replace('/(.+\\.[A-Z]+)[^A-Z]*$/i',"\$1",trim($val)); + $contacts[trim($val)]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>trim($val)); + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + if (file_exists($this->getLogoutPath())) + { + $url_logout=file_get_contents($this->getLogoutPath()); + if (!empty($url_logout)) $res=$this->get($url_logout,true); + } + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/wpl.plg.php b/plugins/contact_importer/OpenInviter/plugins/wpl.plg.php new file mode 100755 index 00000000..6ca6acfa --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/wpl.plg.php @@ -0,0 +1,157 @@ +<?php +$_pluginInfo=array( + 'name'=>'Wp.pt', + 'version'=>'1.0.3', + 'description'=>"Get the contacts from an Wp.pt account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://wap.poczta.wp.pl/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Wp.pt Plugin + * + * Imports user's contacts from Wp.pt account + * + * @author OpenInviter + * @version 1.0.0 + */ +class wpl extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array('initial_get'=>'zaloguj', + 'login_post'=>'addresses.html', + 'url_adress'=>'addraction', + 'url_contact'=>'info' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='wp'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res = $this->get("http://wap.poczta.wp.pl/",true); + + + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://wap.poczta.wp.pl/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://wap.poczta.wp.pl/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://wap.poczta.wp.pl/index.html"; + $post_elements=array('login'=>$user, + 'password'=>$pass, + 'zaloguj'=>'Zaloguj' + ); + + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_adress='http://wap.poczta.wp.pl/addresses.html?'.$this->getElementString($res,'addresses.html?','"'); + $this->login_ok=$url_adress; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("url_adress",$res)) + $this->updateDebugBuffer('url_adress',$url,'GET'); + else + { + $this->updateDebugBuffer('url_adress',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts=array(); + $href_array=$this->getElementDOM($res,"//a[@href]",'href'); + foreach ($href_array as $value) + if (strpos($value,'addresses.html?action=addraction&aid=')!==false) + { + + $res=$this->get("http://wap.poczta.wp.pl/{$value}"); + if ($this->checkResponse("url_contact",$res)) + $this->updateDebugBuffer('url_contact',"http://wap.poczta.wp.pl/{$value}",'GET'); + else + { + $this->updateDebugBuffer('url_contact',"http://wap.poczta.wp.pl/{$value}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts_array=$this->getElementDOM($res,"//p[@class='info']"); + $contacts_exploded=explode(' <',$contacts_array[0]);$email=str_replace('>','',$contacts_exploded[1]);$name=trim(preg_replace('/[^(\x20-\x7F)]*/','',$contacts_exploded[0])); + $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://wap.poczta.wp.pl/'); + $url_logout='http://wap.poczta.wp.pl/index.html?logout=1&ticaid='.$this->getElementString($res,'index.html?logout=1&ticaid=','"'); + $res=$this->get($url_logout); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/xanga.plg.php b/plugins/contact_importer/OpenInviter/plugins/xanga.plg.php new file mode 100755 index 00000000..6cc2fd21 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/xanga.plg.php @@ -0,0 +1,188 @@ +<?php +$_pluginInfo=array( + 'name'=>'Xanga', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from a Xanga account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://www.xanga.com/', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Xanga Plugin + * + * Import user's contacts from Xanga and send + * messages using the internal messaging system + * + * @author OpenInviter + * @version 1.0.0 + */ +class xanga extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'txtSigninPassword', + 'post_login'=>'home.aspx', + 'get_friends'=>'thumbnail', + 'url_send_message'=>'messagesubject', + 'send_message'=>'private' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='xanga'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.xanga.com/signin.aspx?ReturnUrl=http%3a%2f%2fwww.xanga.com%2fdefault.aspx"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://hk.xanga.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://hk.xanga.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.xanga.com/signin.aspx?ReturnUrl=http%3a%2f%2fwww.xanga.com%2fdefault.aspx"; + $post_elements=$this->getHiddenElements($res); + $post_elements['txtSigninUsername']=$user;$post_elements['txtSigninPassword']=$pass;$post_elements['cmbNetwork']=1;$post_elements['signInButton']='Sign In'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("post_login",$res)) + $this->updateDebugBuffer('post_login',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends="http://www.xanga.com/private/homemain.aspx"; + $this->login_ok=$url_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + $contacts=array(); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@class='thumbnail']";$data=$xpath->query($query); + foreach($data as $node) + if (strpos($node->getAttribute('title'),'Visit')!==false) + { + $href=$node->getAttribute('href'); + if (!empty($href)) $name=$this->getElementString($href,'//','.'); + if (!empty($name)) $contacts[$href]=!empty($name)?$name:false; + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message="http://www.xanga.com/message.aspx?user={$name}"; + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action=$url_send_message; + $post_elements=$this->getHiddenElements($res);$post_elements['messagesubject']=$message['subject'];$post_elements['messagetext']=$message['body'];$post_elements['btnSubmit']='Submit'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://www.xanga.com/logout.aspx",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/xing.plg.php b/plugins/contact_importer/OpenInviter/plugins/xing.plg.php new file mode 100755 index 00000000..381de953 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/xing.plg.php @@ -0,0 +1,207 @@ +<?php +$_pluginInfo=array( + 'name'=>'Xing', + 'version'=>'1.0.6', + 'description'=>"Get the contacts from a Xing account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'https://mobile.xing.com/', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Xing Plugin + * + * Import user's contacts from Xing and send + * messages using the internal messaging system + * + * @author OpenInviter + * @version 1.0.0 + */ +class xing extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'dest', + 'post_login'=>'white', + 'get_friends'=>'normal_link', + 'get_url_send_message'=>'light_grey_bg', + 'url_send_message'=>'private_message.send', + 'send_message'=>'light_grey_bg' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='xing'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://mobile.xing.com/"); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"https://mobile.xing.com/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://mobile.xing.com/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="https://mobile.xing.com/".$this->getElementString($res,'form action="','"'); + $post_elements=array('op'=>'login', + 'dest'=>'/app/user?op=home', + 'login_user_name'=>$user, + 'login_password'=>$pass, + 'sv-remove-name'=>'Log in' + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("post_login",$res)) + $this->updateDebugBuffer('post_login',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('post_login',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_adressbook_array=$this->getElementDOM($res,"//a[@class='white']",'href'); + $url_adressbook='https://mobile.xing.com'.$url_adressbook_array[3]; + $this->login_ok=$url_adressbook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url,true); + $contacts=array(); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $contacts_href=$this->getElementDOM($res,"//a[@class='normal_link']",'href'); + $contacts_name=$this->getElementDOM($res,"//a[@class='normal_link']"); + foreach ($contacts_name as $key=>$value) + if (!empty($contacts_href[$key])) $contacts[$contacts_href[$key]]=!empty($value)?$value:false; + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_friend="https://mobile.xing.com{$href}"; + $res=$this->get($url_friend,true); + if ($this->checkResponse("get_url_send_message",$res)) + $this->updateDebugBuffer('get_url_send_message',$url_friend,'GET'); + else + { + $this->updateDebugBuffer('get_url_send_message',$url_friend,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//div[@class='light_grey_bg']";$data=$xpath->query($query); + foreach($data as $node) $url_send_message='https://mobile.xing.com/'.$node->nextSibling->getAttribute('href'); + $res=$this->get($url_send_message,true); + if (strpos($res,'Only XING Premium')===false) + { + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $form_action="https://mobile.xing.com/".$this->getElementString($res,'form action="/','"'); + $post_elements=$this->getHiddenElements($res);$post_elements['subject']=$message['subject']; + $post_elements['body']=$message['body'];$post_elements['sv-set-op-to-private_message.send']='Send'; + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("post_login",$res)) + $this->updateDebugBuffer('send_message',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + } + else return true; + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("https://www.xing.com/app/user?op=logout",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/xuqa.plg.php b/plugins/contact_importer/OpenInviter/plugins/xuqa.plg.php new file mode 100755 index 00000000..e0f83314 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/xuqa.plg.php @@ -0,0 +1,209 @@ +<?php +/*Import Friends from Lovento + * You can Posts Messages using Xuqa system + */ +$_pluginInfo=array( + 'name'=>'Xuqa', + 'version'=>'1.0.5', + 'description'=>"Get the contacts from a Xuqa account", + 'base_version'=>'1.8.0', + 'type'=>'social', + 'check_url'=>'http://xuqa.com/login.php?dest=%2Findex.php&query_str=', + 'requirement'=>'email', + 'allowed_domains'=>false, + ); +/** + * Xuqa Plugin + * + * Import Friends from Xuqa + * You can Write Private Messages using Xuqa system + * + * @author OpenInviter + * @version 1.0.3 + */ +class xuqa extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + public $internalError=false; + protected $timeout=30; + + public $debug_array=array( + 'initial_get'=>'email_1', + 'login_post'=>'logout', + 'url_all_friends'=>'shadetabs', + 'get_friends'=>'name', + 'url_send_message'=>'book_id', + 'send_message'=>'book_id' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='xuqa'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://xuqa.com/login.php?dest=%2Findex.php&query_str=",true); + if ($this->checkResponse("initial_get",$res)) + $this->updateDebugBuffer('initial_get',"http://www.xuqa.com/en/",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.xuqa.com/en/",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://xuqa.com/redirect-login.php?cmd=submit&"; + $post_elements=array('email_1'=>$user,'password'=>$pass,'loginform_Submit'=>'submit'); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("login_post",$res)) + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $url_friends='http://xuqa.com/friends.php'; + $res=$this->get($url_friends,true); + if ($this->checkResponse("url_all_friends",$res)) + $this->updateDebugBuffer('url_all_friends',$url_friends,'GET'); + else + { + $this->updateDebugBuffer('url_all_friends',$url_friends,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_all_friends='http://xuqa.com/ajax/friends.php?search=all_friend&tabs=shadetabs=0&id='.$this->getElementString($res,'shadetabs=0&id=','"'); + $this->login_ok=$url_all_friends; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + $res=$this->get($url); + if ($this->checkResponse("get_friends",$res)) + $this->updateDebugBuffer('get_friends',$url,'GET'); + else + { + $this->updateDebugBuffer('get_friends',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//span[@id='name']";$data=$xpath->query($query); + foreach($data as $node) + { + $name=$node->nodeValue; + $href=$node->parentNode->getAttribute('href'); + if (!empty($href)) $contacts[$href]=(!empty($name)?$name:false); + } + return $contacts; + } + + /** + * Send message to contacts + * + * Sends a message to the contacts using + * the service's inernal messaging system + * + * @param string $cookie_file The location of the cookies file for the current session + * @param string $message The message being sent to your contacts + * @param array $contacts An array of the contacts that will receive the message + * @return mixed FALSE on failure. + */ + public function sendMessage($session_id,$message,$contacts) + { + $countMessages=0; + foreach($contacts as $href=>$name) + { + $countMessages++; + $url_send_message=str_replace('1','scrapbook.php?id=1',$href); + $res=$this->get($url_send_message,true); + if ($this->checkResponse("url_send_message",$res)) + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET'); + else + { + $this->updateDebugBuffer('url_send_message',$url_send_message,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://xuqa.com/scrapbook.php'.$this->getElementString($res,'name="scrap_post" method="post" action="','"'); + $book_id=$this->getElementDOM($res,"//input[@name='book_id']",'value'); + $post_elements=array('cmd'=>'post', + 'book_id'=>$book_id[0], + 'comment'=>$message['body'], + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse("send_message",$res)) + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('send_message',"{$form_action}",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + sleep($this->messageDelay); + if ($countMessages>$this->maxMessages) {$this->debugRequest();$this->resetDebugger();$this->stopPlugin();break;} + } + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://xuqa.com/login.php"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + } + +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/yahoo.plg.php b/plugins/contact_importer/OpenInviter/plugins/yahoo.plg.php new file mode 100755 index 00000000..164bb1f7 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/yahoo.plg.php @@ -0,0 +1,188 @@ +<?php +$_pluginInfo=array( + 'name'=>'Yahoo!', + 'version'=>'1.4.9', + 'description'=>"Get the contacts from a Yahoo! account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://mail.yahoo.com', + 'requirement'=>'email', + 'allowed_domains'=>array('/(yahoo)/i','/(ymail)/i','/(rocketmail)/i'), + ); +/** + * Yahoo! Plugin + * + * Imports user's contacts from Yahoo!'s AddressBook + * + * @author OpenInviter + * @version 1.3.8 + */ +class yahoo extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'initial_get'=>'form: login information', + 'login_post'=>'window.location.replace', + 'contacts_page'=>'.crumb', + 'contacts_file'=>'"' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='yahoo'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("https://login.yahoo.com/config/mail?.intl=us&rl=1"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"https://login.yahoo.com/config/mail?.intl=us&rl=1",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://login.yahoo.com/config/mail?.intl=us&rl=1",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=$this->getHiddenElements($res);$post_elements["save"]="Sign+In";$post_elements['login']=$user;$post_elements['passwd']=$pass; + $res=htmlentities($this->post("https://login.yahoo.com/config/login?",$post_elements,true)); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',"https://login.yahoo.com/config/login?",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"https://login.yahoo.com/config/login?",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + $this->login_ok=$this->login_ok="http://address.mail.yahoo.com/?_src=&VPC=tools_export"; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + $url=$this->login_ok; + $contacts=array(); + $res=$this->get($url,true); + if ($this->checkResponse("contacts_page",$res)) + $this->updateDebugBuffer('contacts_page',"{$url}",'GET'); + else + { + $this->updateDebugBuffer('contacts_page',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $post_elements=array('VPC'=>'import_export', + '.crumb'=>$this->getElementString($res,'id="crumb1" value="','"'), + 'submit[action_export_yahoo]'=>'Export Now' + ); + $res=$this->post("http://address.mail.yahoo.com/?_src=&VPC=tools_export",$post_elements); + if ($this->checkResponse("contacts_file",$res)) + { + $temp=$this->parseCSV($res, ',', '/\r\n/'); + $contacts=array(); + if (!empty($temp)) foreach ($temp as $values) + { + if (!empty($values['7'])) $mess_id=(!$this->isEmail($values['7'])?"{$values['7']}@yahoo.com":$values['7']); + if (!empty($values[4])) $emailKey=$values[4]; + elseif(!empty($mess_id)) $emailKey=$mess_id; + elseif(!empty($values['52'])) $emailKey=$values['52']; + if (!empty($emailKey)) + $contacts[$emailKey]=array('first_name'=>(!empty($values[0])?$values[0]:false), + 'middle_name'=>(!empty($values[2])?$values[2]:false), + 'last_name'=>(!empty($values[1])?$values[1]:false), + 'nickname'=>(!empty($values[3])?$values[3]:false), + 'email_1'=>(!empty($values[4])?$values[4]:$emailKey), + 'email_2'=>(!empty($values[17])?$values[17]:false), + 'email_3'=>(!empty($values[16])?$values[16]:false), + 'organization'=>false, + 'phone_mobile'=>(!empty($values[12])?$values[12]:false), + 'phone_home'=>(!empty($values[8])?$values[8]:false), + 'pager'=>(!empty($values[10])?$values[10]:false), + 'address_home'=>(!empty($values[27])?$values[27]:false), + 'address_city'=>(!empty($values[28])?$values[28]:false), + 'address_state'=>(!empty($values[29])?$values[29]:false), + 'address_country'=>(!empty($values[31])?$values[31]:false), + 'postcode_home'=>(!empty($values[30])?$values[30]:false), + 'company_work'=>(!empty($values[21])?$values[21]:false), + 'address_work'=>(!empty($values[2])?$values[22]:false), + 'address_work_city'=>(!empty($values[23])?$values[16]:false), + 'address_work_country'=>(!empty($values[26])?$values[26]:false), + 'address_work_state'=>(!empty($values[24])?$values[24]:false), + 'address_work_postcode'=>(!empty($values[25])?$values[25]:false), + 'fax_work'=>false, + 'phone_work'=>(!empty($values[20])?$values[20]:false), + 'website'=>(!empty($values[18])?$values[18]:false), + 'isq_messenger'=>(!empty($values[50])?$values[50]:false), + 'skype_essenger'=>(!empty($values[48])?$values[48]:false), + 'yahoo_essenger'=>(!empty($values[39])?$values[39]:false), + 'msn_messenger'=>(!empty($values[52])?$values[52]:false), + 'aol_messenger'=>(!empty($values[53])?$values[53]:false), + 'other_messenger'=>false, + ); + } + $this->updateDebugBuffer('contacts_file',"http://address.mail.yahoo.com/index.php",'POST',true,$post_elements); + } + else + { + $this->updateDebugBuffer('contacts_file',"http://address.mail.yahoo.com/index.php",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get("http://login.yahoo.com/config/login?logout=1&.done=http://address.yahoo.com&.src=ab&.intl=us"); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/yandex.plg.php b/plugins/contact_importer/OpenInviter/plugins/yandex.plg.php new file mode 100755 index 00000000..6cc4f0b3 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/yandex.plg.php @@ -0,0 +1,120 @@ +<?php +$_pluginInfo=array( + 'name'=>'Yandex', + 'version'=>'1.1.0', + 'description'=>"Get the contacts from a Yandex account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://yandex.ru', + 'requirement'=>'email', + 'allowed_domains'=>array('/(yandex.ru)/i'), + ); +/** + * Yandex Plugin + * + * Imports user's contacts from his Yandex + * AddressBook. + * + * @author OpenInviter + * @version 1.0.5 + */ +class yandex extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'main_redirect'=>'window.location.replace("', + 'log_in'=>'http://passport.yandex.ru/passport?mode=logout', + 'url_contacts'=>'abook_person?ids' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user, $pass) + { + $this->resetDebugger(); + $this->service='yandex'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res = $this->get("http://yandex.ru/",false); + $res = $this->get("http://mail.yandex.ru/",true); + $postaction = "https://passport.yandex.ru/passport?mode=auth"; + $postelem = $this->getHiddenElements($res);$postelem["login"]=$user;$postelem["passwd"]=$pass; + $res = $this->post($postaction, $postelem, true); + $linkToAddressBook = "http://mail.yandex.ru/classic/abook"; + $this->login_ok = $linkToAddressBook; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url = $this->login_ok; + $res = $this->get($url, true); + if ($this->checkResponse("url_contacts",$res)) + $this->updateDebugBuffer('url_contacts',$url,'GET'); + else + { + $this->updateDebugBuffer('url_contacts',$url,'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts = array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a";$data=$xpath->query($query); + foreach($data as $node) + { + if (strpos($node->getAttribute('href'),'compose?to')!==false) $email=$node->nodeValue; + if (strpos($node->getAttribute('href'),'abook_person?ids')!==false) $name=$node->nodeValue; + if (!empty($email)) + $contacts[$email]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$email); + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res = $this->get(urldecode("http://passport.yandex.ru/passport?mode=logout&retpath=http%3A%2F%2Fwww.yandex.ru%2F")); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/youtube.plg.php b/plugins/contact_importer/OpenInviter/plugins/youtube.plg.php new file mode 100755 index 00000000..2784d59b --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/youtube.plg.php @@ -0,0 +1,193 @@ +<?php +$_pluginInfo=array( + 'name'=>'YouTube', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from a YouTube account AddressBook ", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.youtube.com', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Youtube Plugin + * + * Imports user's contacts from YouTube AddressBook and + + * + * @author OpenInviter + * @version 1.0.0 + */ +class youtube extends openinviter_base +{ + private $login_ok=false; + public $showContacts=true; + public $debug_array=array( + 'initial_get'=>'ltmpl', + 'login_post'=>'location.replace(', + 'url_redirect'=>'gXSRF_token', + 'url_addressbook'=>'YT_address_book', + 'url_contacts'=>'fid' + + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='youtube'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + $res=$this->get("https://www.google.com/accounts/ServiceLogin?uilel=3&service=youtube&passive=true&continue=http%3A%2F%2Fwww.youtube.com%2Fsignup%3Fnomobiletemp%3D1%26hl%3Den_US%26next%3D%252F&hl=en_US<mpl=sso"); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"https://www.google.com/accounts/ServiceLogin?uilel=3&service=youtube&passive=true&continue=http%3A%2F%2Fwww.youtube.com%2Fsignup%3Fnomobiletemp%3D1%26hl%3Den_US%26next%3D%252F&hl=en_US<mpl=sso",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"https://www.google.com/accounts/ServiceLogin?uilel=3&service=youtube&passive=true&continue=http%3A%2F%2Fwww.youtube.com%2Fsignup%3Fnomobiletemp%3D1%26hl%3Den_US%26next%3D%252F&hl=en_US<mpl=sso",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="https://www.google.com/accounts/ServiceLoginAuth?service=youtube"; + $post_elements=array('ltmpl'=>'sso', + 'continue'=>'http://www.youtube.com/signin?action_handle_signin=true&nomobiletemp=1&hl=en_US&next=%2Findex', + 'next'=>'/', + 'service'=>'youtube', + 'uilel'=>3, + 'ltmpl'=>'sso', + 'hl'=>'en_US', + 'ltmpl'=>'sso', + 'GALX'=>$this->getElementString($res,'name="GALX" value="','"'), + 'Email'=>$user, + 'Passwd'=>$pass, + 'PersistentCookie'=>'yes', + 'rmShown'=>1, + 'signIn'=>'Sign in', + 'asts'=>false, + ); + $res=$this->post($form_action,$post_elements,true,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_redirect=html_entity_decode(urldecode(str_replace('\x', '%', $this->getElementString($res,'location.replace("','"')))); + $res=$this->get($url_redirect,true); + if ($this->checkResponse('url_redirect',$res)) + $this->updateDebugBuffer('url_redirect',"{$url_redirect}",'GET'); + else + { + $this->updateDebugBuffer('url_redirect',"{$url_redirect}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $this->login_ok='http://www.youtube.com/address_book'; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if ($this->login_ok===false) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else $url=$this->login_ok; + + $res=$this->get($url); + if ($this->checkResponse('url_addressbook',$res)) + $this->updateDebugBuffer('url_addressbook',"{$url}",'GET'); + else + { + $this->updateDebugBuffer('url_addressbook',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action='http://www.youtube.com/address_book?action_ajax=1'; + $post_elements=array('session_token'=>$this->getElementString($res,"YT_address_book('session_token=","'"), + 'messages'=>'[{"type":"ajax_fetch_contacts","request":{"gid":"_all_contacts_","link_count":1000,"page":1}}]', + ); + $res=$this->post($form_action,$post_elements); + if ($this->checkResponse('url_contacts',$res)) + $this->updateDebugBuffer('url_contacts',$form_action,'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('url_contacts',$form_action,'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + if (preg_match_all("#fid\"\: \"(.+)\"\}#U", $res, $matchesArray)) + { + if (!empty($matchesArray[1])) + foreach($matchesArray[1] as $dummy=>$id) + { + $emailsArray=array();$namesArray=array(); + $res=$this->get("http://www.youtube.com/address_book?action_display_contact_details=1&fid={$id}"); + if (preg_match_all("#mailto\:(.+)\"#U", $res, $emailsArray)) + { + if (preg_match_all("#\"\/user\/(.+)\"#U", $res, $namesArray)) $contacts[$emailsArray[1][0]]=array('first_name'=>$namesArray[1][0],'email_1'=>$emailsArray[1][0]); + else $contacts[$emailsArray[1][0]]=array('first_name'=>$emailsArray[1][0],'email_1'=>$emailsArray[1][0]); + } + } + } + foreach ($contacts as $email=>$dummy) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + $res=$this->get('http://www.youtube.com/index',true); + $post_elements=array('action_logout'=>1, + 'session_token'=>$this->getElementString($res,"YT_php_support('","'"), + ); + $res=$this->post('http://www.youtube.com/index',$post_elements,true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } +} +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/plugins/zapak.plg.php b/plugins/contact_importer/OpenInviter/plugins/zapak.plg.php new file mode 100755 index 00000000..a817c66e --- /dev/null +++ b/plugins/contact_importer/OpenInviter/plugins/zapak.plg.php @@ -0,0 +1,152 @@ +<?php +$_pluginInfo=array( + 'name'=>'Zapakmail', + 'version'=>'1.0.2', + 'description'=>"Get the contacts from an Zapakmail account", + 'base_version'=>'1.8.0', + 'type'=>'email', + 'check_url'=>'http://www.zapak.com/zapakmail.zpk', + 'requirement'=>'user', + 'allowed_domains'=>false, + ); +/** + * Zapakmail Plugin + * + * Imports user's contacts from Zapakmail's AddressBook + * + * @author OpenInviter + * @version 1.6.5 + */ +class zapak extends openinviter_base + { + private $login_ok=false; + public $showContacts=true; + protected $timeout=30; + public $debug_array=array( + 'initial_get'=>'uid', + 'login_post'=>'msgid', + 'url_adress'=>'onclick' + ); + + /** + * Login function + * + * Makes all the necessary requests to authenticate + * the current user to the server. + * + * @param string $user The current user. + * @param string $pass The password for the current user. + * @return bool TRUE if the current user was authenticated successfully, FALSE otherwise. + */ + public function login($user,$pass) + { + $this->resetDebugger(); + $this->service='zapakmail'; + $this->service_user=$user; + $this->service_password=$pass; + if (!$this->init()) return false; + + $res=$this->get("http://www.zapak.com/zapakmail.zpk",true); + if ($this->checkResponse('initial_get',$res)) + $this->updateDebugBuffer('initial_get',"http://www.zapak.com/zapakmail.zpk",'GET'); + else + { + $this->updateDebugBuffer('initial_get',"http://www.zapak.com/zapakmail.zpk",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $form_action="http://www.zapak.com/authenticateuser.zpk?redirect=/emailr.zpk? "; + $post_elements=array('uid'=>$user, + 'password'=>$pass, + 'Submit32.x'=>rand(10,50), + 'Submit32.y'=>rand(10,50), + 'isemail'=>'y', + 'regflag'=>1 + ); + $res=$this->post($form_action,$post_elements,true); + if ($this->checkResponse('login_post',$res)) + $this->updateDebugBuffer('login_post',"$form_action",'POST',true,$post_elements); + else + { + $this->updateDebugBuffer('login_post',"$form_action",'POST',false,$post_elements); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $url_address='http://www.zapak.com/mc.zpk'; + $this->login_ok=$url_address; + return true; + } + + /** + * Get the current user's contacts + * + * Makes all the necesarry requests to import + * the current user's contacts + * + * @return mixed The array if contacts if importing was successful, FALSE otherwise. + */ + public function getMyContacts() + { + if (!$this->login_ok) + { + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + else + $url=$this->login_ok; + //go to url inbox + $res=$this->get($url,true); + if ($this->checkResponse("url_adress",$res)) + $this->updateDebugBuffer('url_adress',"{$url}",'GET'); + else + { + $this->updateDebugBuffer('url_adress',"{$url}",'GET',false); + $this->debugRequest(); + $this->stopPlugin(); + return false; + } + + $contacts=array(); + $doc=new DOMDocument();libxml_use_internal_errors(true);if (!empty($res)) $doc->loadHTML($res);libxml_use_internal_errors(false); + $xpath=new DOMXPath($doc);$query="//a[@onclick]";$data=$xpath->query($query); + foreach($data as $node) + { + if ($node->nodeValue=='Edit') + { + $emails=str_replace('firstname=',"",str_replace("lastname=","",str_replace("email=","",$this->getElementString((string)$node->getAttribute('onclick'),'?','&id')))); + $emails_array=explode("&",$emails); + $name=(isset($emails_array[0])?$emails_array[0]:false)." ".(isset($emails_array[1])?$emails_array[1]:false); + if ($emails_array[2]) + $contacts[$emails_array[2]]=array('first_name'=>(!empty($name)?$name:false),'email_1'=>$emails_array[2]); + } + } + foreach ($contacts as $email=>$name) if (!$this->isEmail($email)) unset($contacts[$email]); + return $this->returnContacts($contacts); + } + + /** + * Terminate session + * + * Terminates the current user's session, + * debugs the request and reset's the internal + * debudder. + * + * @return bool TRUE if the session was terminated successfully, FALSE otherwise. + */ + public function logout() + { + if (!$this->checkSession()) return false; + echo $res=$this->get("http://www.zapak.com/mlor.z?zmail=y",true); + $this->debugRequest(); + $this->resetDebugger(); + $this->stopPlugin(); + return true; + } + + } +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/postinstall.php.ignore b/plugins/contact_importer/OpenInviter/postinstall.php.ignore new file mode 100755 index 00000000..7768b221 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/postinstall.php.ignore @@ -0,0 +1,212 @@ +<?php +set_time_limit(0); +$rewrite_config=false; +include('config.php'); + +function row2text($row) + { + $text=''; + $flag=0; + $i=0; + foreach ($row as $var=>$val) + { + if($flag==1) + $text.=", "; + elseif($flag==2) + $text.=",\n"; + $flag=1; + //Variable + if(is_numeric($var)) + if($var{0}=='0') + $text.="'$var'=>"; + else + { + if($var!==$i) + $text.="$var=>"; + $i=$var; + } + else + $text.="'$var'=>"; + $i++; + //letter + if(is_array($val)) + { + $text.="array(".row2text($val).")"; + $flag=2; + } + else + $text.="\"$val\""; + } + return($text); + } + +function display_message($msg) + { + global $contents; + $contents.=$msg; + echo $msg; + } + +function check_cache() + { + if (file_exists('postinstall_results.res')) + if (time()-filemtime('postinstall_results.res')<120) { echo file_get_contents('postinstall_results.res'); exit; } + } + +check_cache(); +$contents=''; + +//Check username and private key +display_message("Checking username and private key... "); +if (empty($openinviter_settings['username']) OR empty($openinviter_settings['private_key'])) + { + display_message("Username or private key missing.Get your own at <a href='http://openinviter.com/register.php'>OpenInviter</a><br>\n"); + exit; + } +else display_message("*OK*<br>\n"); + +//Check PHP version +display_message("Checking PHP version... "); +if (version_compare(PHP_VERSION, '5.0.0', '<')) { display_message("*NOT OK* - OpenInviter requires PHP5, your server has PHP ".PHP_VERSION." installed");exit; } +else display_message("*OK*<br>\n"); + +//Check support for DOMDocument +display_message("Checking DOMDocument support... "); +if (!extension_loaded('dom') OR !class_exists('DOMDocument')) { display_message("*NOT OK* - OpenInviter will not run correctly on this system.");exit; } +else display_message("*OK*<br>\n"); + +//Check transport type +$transport='curl'; +display_message("Checking transport method... "); +if (!extension_loaded('curl') OR !function_exists('curl_init')) + { + $transport='wget'; + passthru("wget --version",$return_var); + if ($return_var!=0) + { + display_message("Neither <b>libcurl</b> nor <b>wget</b> is installed.<br>\nYou will not be able to use OpenInviter."); + exit; + } + else display_message("<b>wget</b> is installed. Using <b>Wget</b> to handle requests<br>\n"); + } +else display_message("<b>libcurl</b> is installed. Using <b>cURL</b> to handle requests<br>\n"); +if ($openinviter_settings['transport']!=$transport) { $rewrite_config=true;$openinviter_settings['transport']=$transport; } + +//Check if stats are available +if (!extension_loaded('SQLite') OR !function_exists('sqlite_open')) + { + $stats=false; + display_message("<b>SQLite</b> is NOT installed. Unable to keep stats<br>\n"); + } +else + { + $stats=true; + display_message("<b>SQLite</b> is installed. Stats enabled. Please define a stats username and password in config.php<br>\n"); + } +if ($openinviter_settings['stats']!=$stats) { $rewrite_config=true;$openinviter_settings['stats']=$stats; } + +//Check permisions +$cookie_path='/tmp'; +display_message("Checking write permisions... "); +if (!is_writable("{$cookie_path}")) + { + $cookie_path = session_save_path(); + if (strpos ($cookie_path, ";") !== FALSE) + $cookie_path = substr ($cookie_path, strpos ($cookie_path, ";")+1); + if (empty($cookie_path)) $cookie_path='/tmp'; + if (!is_writable("{$cookie_path}")) + { + display_message("The <b>{$cookie_path}</b> folder is not writable. You will have to manually define a location for logs and temporary files in <b>config.php</b><br>\n"); + exit; + } + else display_message("<b>{$cookie_path}</b> is writable. Using <b>{$cookie_path}</b> to store cookie files and logs<br>\n"); + } +else display_message("<b>{$cookie_path}</b> is writable. Using <b>{$cookie_path}</b> to store cookie files and logs<br>\n"); +if ($openinviter_settings['cookie_path']!=$cookie_path) { $rewrite_config=true;$openinviter_settings['cookie_path']=$cookie_path; } + +//Write new config file if required +if ($rewrite_config) + { + $file_contents="<?php\n"; + $file_contents.="\$openinviter_settings=array(\n".row2text($openinviter_settings).");\n"; + $file_contents.="?>"; + file_put_contents('config.php',$file_contents); + } + +//Instantiate OpenInviter +include('openinviter.php'); +$inviter=new OpenInviter(); + +class PostInstall extends OpenInviter_Base + { + public function login($user,$pass) + { + return; + } + public function getMyContacts() + { + return; + } + public function logout() + { + return; + } + public function checkVersion() + { + $this->init(); + $res=$this->get("http://update.openinviter.com/updater/check_version.php?key={$this->settings['private_key']}"); + $this->stopPlugin(); + return $res; + } + public function check($url) + { + $this->init(); + $res=$this->get($url); + $this->stopPlugin(); + if (empty($res)) return false; else return true; + } + } + +$checker=new PostInstall(); +$checker->settings=$inviter->settings; +$checker->service_user='postInstall'; +$checker->service_pass='postInstall'; +$checker->service='postInstall'; + +//Check version +display_message("Checking for new versions of OpenInviter... "); +$xml=$checker->checkVersion(); +libxml_use_internal_errors(true); +$parsed_xml=simplexml_load_string($xml); +libxml_use_internal_errors(false); +if (!$parsed_xml) + display_message("Could not connect to server<br>\n"); +else + { + $server_version=(string)$parsed_xml; + $version=$inviter->getVersion(); + if (!$inviter->checkVersion($server_version)) display_message("You are using OpenInviter <b>{$version}</b> but version <b>{$server_version}</b> is available for download - <a href='http://openinviter.com/download.php'>Download newer version</a><br>\n"); + else display_message("Your OpenInviter software is up-to-date<br>\n"); + } + +//Check plugins +if ($openinviter_settings['hosted']) + { + display_message("Running in `Hosted` mode..."); + display_message("Checking OpenInviter Hosted Solution server..."); + if ($checker->check('http://hosted.openinviter.com')) display_message("*OK*<br>\n"); else display_message("*NOT OK* - You might not be able to use the OpenInviter Hosted Solution"); + } +else + { + $plugins=$inviter->getPlugins(); + foreach ($plugins as $type=>$dummy) + foreach ($dummy as $plugin=>$details) + { + display_message("Checking {$details['name']}... "); + if ($checker->check($details['check_url'])) display_message("*OK*<br>\n"); else display_message("*NOT OK* - This plugin might not work correctly on your system<br>\n"); + } + } + +display_message("<br><b>WARNING:</b> Delete postinstall.php before running OpenInviter. Also please note that you cannot run postinstall.php again for 2 minutes."); +file_put_contents('postinstall_results.res',$contents); +?> \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/postinstall_results.res b/plugins/contact_importer/OpenInviter/postinstall_results.res new file mode 100755 index 00000000..b56928c6 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/postinstall_results.res @@ -0,0 +1,111 @@ +Checking username and private key... *OK*<br> +Checking PHP version... *OK*<br> +Checking DOMDocument support... *OK*<br> +Checking transport method... <b>libcurl</b> is installed. Using <b>cURL</b> to handle requests<br> +<b>SQLite</b> is NOT installed. Unable to keep stats<br> +Checking write permisions... <b>C:\WINDOWS\Temp</b> is writable. Using <b>C:\WINDOWS\Temp</b> to store cookie files and logs<br> +Checking for new versions of OpenInviter... Your OpenInviter software is up-to-date<br> +Checking Abv... *OK*<br> +Checking AOL... *OK*<br> +Checking Apropo... *OK*<br> +Checking Atlas... *OK*<br> +Checking Aussiemail... *OK*<br> +Checking Azet... *OK*<br> +Checking Bigstring... *OK*<br> +Checking Bordermail... *OK*<br> +Checking Canoe... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Care2... *OK*<br> +Checking Clevergo... *OK*<br> +Checking Doramail... *OK*<br> +Checking Evite... *OK*<br> +Checking FastMail... *OK*<br> +Checking 5Fm... *OK*<br> +Checking Freemail... *OK*<br> +Checking Gawab... *OK*<br> +Checking GMail... *OK*<br> +Checking GMX.net... *OK*<br> +Checking Grafitti... *OK*<br> +Checking Live/Hotmail... *OK*<br> +Checking Hushmail... *OK*<br> +Checking Inbox.com... *OK*<br> +Checking India... *OK*<br> +Checking IndiaTimes... *OK*<br> +Checking Inet... *OK*<br> +Checking Interia... *OK*<br> +Checking KataMail... *OK*<br> +Checking Kids... *OK*<br> +Checking Libero... *OK*<br> +Checking LinkedIn... *OK*<br> +Checking Lycos... *OK*<br> +Checking Mail2World... *OK*<br> +Checking Mail.com... *OK*<br> +Checking Mail.in... *OK*<br> +Checking Mail.ru... *OK*<br> +Checking Meta... *OK*<br> +Checking Mynet.com... *OK*<br> +Checking Netaddress... *OK*<br> +Checking Nz11... *OK*<br> +Checking O2... *OK*<br> +Checking OperaMail... *OK*<br> +Checking Pochta... *OK*<br> +Checking Popstarmail... *OK*<br> +Checking Rambler... *OK*<br> +Checking Rediff... *OK*<br> +Checking Sapo.pt... *OK*<br> +Checking Techemail... *OK*<br> +Checking Terra... *OK*<br> +Checking Uk2... *OK*<br> +Checking Virgilio... *OK*<br> +Checking Walla... *OK*<br> +Checking Web.de... *OK*<br> +Checking Wp.pt... *OK*<br> +Checking Yahoo!... *OK*<br> +Checking Yandex... *OK*<br> +Checking YouTube... *OK*<br> +Checking Zapakmail... *OK*<br> +Checking Badoo... *OK*<br> +Checking Bebo... *OK*<br> +Checking Bookcrossing... *OK*<br> +Checking Brazencareerist... *OK*<br> +Checking Cyworld... *OK*<br> +Checking Eons... *OK*<br> +Checking Facebook... *OK*<br> +Checking Faces... *OK*<br> +Checking Famiva... *OK*<br> +Checking Fdcareer... *OK*<br> +Checking Flickr... *OK*<br> +Checking Flingr... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Flixster... *OK*<br> +Checking Friendfeed... *OK*<br> +Checking Friendster... *OK*<br> +Checking Hi5... *OK*<br> +Checking Hyves... *OK*<br> +Checking Kincafe... *OK*<br> +Checking Konnects... *OK*<br> +Checking Koolro... *OK*<br> +Checking Last.fm... *OK*<br> +Checking Livejournal... *OK*<br> +Checking Lovento... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Meinvz... *OK*<br> +Checking Mevio... *OK*<br> +Checking Motortopia... *OK*<br> +Checking Multiply... *OK*<br> +Checking Mycatspace... *OK*<br> +Checking Mydogspace... *OK*<br> +Checking MySpace... *OK*<br> +Checking NetLog... *OK*<br> +Checking Ning... *OK*<br> +Checking Orkut... *OK*<br> +Checking Perfspot... *OK*<br> +Checking Plaxo... *OK*<br> +Checking Plazes... *OK*<br> +Checking Plurk... *OK*<br> +Checking Skyrock... *OK*<br> +Checking Tagged... *OK*<br> +Checking Twitter... *OK*<br> +Checking Vimeo... *OK*<br> +Checking Vkontakte... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Xanga... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Xing... *NOT OK* - This plugin might not work correctly on your system<br> +Checking Xuqa... *NOT OK* - This plugin might not work correctly on your system<br> +<br><b>WARNING:</b> Delete postinstall.php before running OpenInviter. Also please note that you cannot run postinstall.php again for 2 minutes. \ No newline at end of file diff --git a/plugins/contact_importer/OpenInviter/stats.php b/plugins/contact_importer/OpenInviter/stats.php new file mode 100755 index 00000000..96ccd944 --- /dev/null +++ b/plugins/contact_importer/OpenInviter/stats.php @@ -0,0 +1,85 @@ +<?php +/* + * Created on Jul 16, 2009 + * + * Owner: George + */ +include('openinviter.php'); +$oi=new OpenInviter(); +if (!$oi->settings['stats']) { echo 'Stats not enabled.';exit; } +if (empty($oi->settings['stats_user']) OR empty($oi->settings['stats_password'])) { header('HTTP/1.0 401 Unauthorized');echo 'Stats username/password not defined';exit; } +elseif (!isset($_SERVER['PHP_AUTH_USER'])) + { + header('WWW-Authenticate: Basic realm="OpenInviter Stats"'); + header('HTTP/1.0 401 Unauthorized'); + echo 'Wrong username/password'; + exit; + } +else + { + if ($_SERVER['PHP_AUTH_USER']!=$oi->settings['stats_user'] OR $_SERVER['PHP_AUTH_PW']!=$oi->settings['stats_password']) + { + header('HTTP/1.0 401 Unauthorized'); + echo 'Wrong username/password'; + exit; + } + } + +if (isset($_GET['op'])) + if ($_GET['op']=='reset') + { + $oi->statsQuery("DELETE FROM oi_imports"); + $oi->statsQuery("DELETE FROM oi_messages"); + } + +$plugins=$oi->getPlugins(); +$import_stats=array();$messages_stats=array(); +$res=$oi->statsQuery("SELECT COUNT(id) AS total_imports,SUM(contacts) AS total_contacts,service FROM oi_imports GROUP BY service ORDER BY total_imports DESC,total_contacts DESC"); +while ($row=sqlite_fetch_array($res)) $import_stats[$row['service']]=$row; +$res=$oi->statsQuery("SELECT COUNT(id) AS total_sends,SUM(messages) AS total_messages,service FROM oi_messages GROUP BY service"); +while ($row=sqlite_fetch_array($res)) $messages_stats[$row['service']]=$row; +echo "<style> +.tableDesc{ color:#3d3d3d;font-family:Arial, Helvetica, sans-serif;font-weight:normal;font-size:12px;text-decoration:none; } +.tableDesc td{ text-align:center; } +.table{ border:1px solid #e1e1e1;padding:1px 1px 1px 1px;font-family:Arial, Helvetica, sans-serif;font-weight:normal;font-size:11px; } +.table td { padding:5px; } +.tableFooter{ height:30px;text-align:center;font-family:Arial, Helvetica, sans-serif;font-size:14px;color:#000000;font-weight:600;background-color:#C7DEE6; } +.tableFooter td{ text-align:center; } +.tableHeader{ background-color:#5fb52b;height:21px;font-family:Arial, Helvetica, sans-serif;font-size:12px;color:#FFFFFF;font-weight:bold;text-decoration:none;text-align:left;vertical-align:middle;padding-left:10px; } +.tableHeader td{ text-align:center; } +.tableOddRow{ background-color:#eaeaea;height:32px; } +.tableEvenRow{ background-color:#f5f5f5;height:32px; } +.title{ color:#89BDF6; } +body{ background-color:#F4F3EF; } +a{ color:#FF7E00;font-family:Arial, Helvetica, sans-serif;font-weight:bold;font-size:14px; } +</style>"; +echo "<center><h1 class='title'>OpenInviter Stats</h1></center>"; +echo "<table class='table' align='center' cellspacing='0' cellpadding='0' width='500'> + <tr class='tableHeader'><td colspan='5'>OpenInviter Statistics</td></tr>"; +if (!empty($import_stats)) + { + echo "<tr class='tableDesc'><td>Service</td><td>Users who imported contacts</td><td>Contacts imported</td><td>Users who sent messages</td><td>Messages sent</td></tr>"; + $total_imports=0;$total_contacts=0;$total_sends=0;$total_messages=0;$odd=true; + foreach ($import_stats as $service=>$details) + { + $total_imports+=$details['total_imports']; + $total_contacts+=$details['total_contacts']; + echo "<tr class='".($odd?'tableOddRow':'tableEvenRow')."'><td><b>".(isset($plugins['email'][$service])?$plugins['email'][$service]['name']:(isset($plugins['social'][$service])?$plugins['social'][$service]['name']:$service))."</b></td><td align='center'>{$details['total_imports']}</td><td align='center'>{$details['total_contacts']}</td>"; + if (isset($messages_stats[$service])) + { + $total_sends+=$messages_stats[$service]['total_sends']; + $total_messages+=$messages_stats[$service]['total_messages']; + echo "<td align='center'>{$messages_stats[$service]['total_sends']}</td><td align='center'>{$messages_stats[$service]['total_messages']}</td>"; + } + else echo "<td align='center'>-</td><td align='center'>-</td>"; + echo "</tr>"; + $odd=!$odd; + } + echo "<tr class='tableFooter'><td>Total</td><td>{$total_imports}</td><td>{$total_contacts}</td><td>{$total_sends}</td><td>{$total_messages}</td></tr> + </table> + <br><center><a href='?op=reset'>Reset statistics</a></center>"; + } +else + echo "<tr class='tableOddRow'><td colspan='5' style='padding:25px;' align='center'>There are no statistics available yet</td></tr></table>"; +echo "<br><center><a target='_blank' href='http://openinviter.com' title='Powered by OpenInviter.com'><img src='http://openinviter.com/images/banners/banner_blue_1.gif' alt='Powered by OpenInviter.com' style='border:none;'></a></center>"; +?> \ No newline at end of file diff --git a/plugins/contact_importer/ReadMe.txt b/plugins/contact_importer/ReadMe.txt new file mode 100755 index 00000000..18f9b0c4 --- /dev/null +++ b/plugins/contact_importer/ReadMe.txt @@ -0,0 +1,29 @@ + +/** + * Contact Importer Plugin (using OpenInviter) + * + * @package ElggContactImporter + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Prashant Juvekar + * @copyright SocialTrak, 2009 + * @link http://www.socialtrak.com + */ + +This module wraps the OpenInviter PHP library and provides +a friendly interface for Elgg installations to add the import +capability. We have exposed only a handful of supported +plugins in the form since these were known to work at the +time of implementation as well as were considered important. +You can tweak the code to add more plugin support. + +This module was developed and is used at www.socialtrak.com +for the purpose of allowing users to invite their friends +from other social networks as well as by importing their +webmail address books. + +Right now, the message sent is hardcoded in but one could +provide a textbox to collect message from the user to tack +onto the default message. + +Feel free to report bugs or requests to admin@socialtrak.com + diff --git a/plugins/contact_importer/import.php b/plugins/contact_importer/import.php new file mode 100755 index 00000000..618c2bcb --- /dev/null +++ b/plugins/contact_importer/import.php @@ -0,0 +1,322 @@ +<?php + + /** + * Contact Importer Plugin (using OpenInviter) + * + * @package ElggContactImporter + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Prashant Juvekar + * @copyright SocialTrak, 2009 + * @link http://www.socialtrak.com + */ + + require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php"); + + global $CONFIG; + + gatekeeper(); + + set_context('friends'); + set_page_owner($_SESSION['guid']); + + //set the title + $body = elgg_view_title(elgg_echo('contact_importer:title')); + + $body .= "<div style='padding:10px;'>"; + + // setup some defaults + $oi_provider = $_POST['oi_provider']; + if ( $oi_provider == null || empty($oi_provider) ) { + $oi_provider = "gmail"; + } + $oi_username = $_POST['oi_username']; + $oi_password = $_POST['oi_password']; + $oi_session_id = $_POST['oi_session_id']; + + // include and initialize openinviter + global $CONFIG; + include ( $CONFIG->path . 'mod/contact_importer/OpenInviter/openinviter.php'); + $inviter=new OpenInviter(); + $oi_services=$inviter->getPlugins(); + + // lookup the provider name + foreach ($oi_services as $type=>$providers) { + foreach ($providers as $provider=>$details) { + if ( $oi_provider == $provider ) { + $oi_provider_name = $details['name']; + } + } + } + + function get_web_mails () { + return array ( + 'aol' => 'AOL', + 'gmail' => 'GMail', + 'hotmail' => 'Live/Hotmail', + 'yahoo' => 'Yahoo!', + ); + } + + function get_social_networks () { + return array ( + 'facebook' => 'Facebook', + 'linkedin' => 'LinkedIn', + 'twitter_ex' => 'Twitter', + 'orkut' => 'Orkut', + ); + } + + function echo_OpenInviter_Inputs_form ($oi_services, $oi_provider, $oi_username) { + + $body = "<form action='' method='POST' name='OpenInviter_Inputs'>"; + $body .= "<table>"; + + $body .= "<tr>"; + $body .= "<td style='width:150px'><label>".elgg_echo('contact_importer:choose_provider')."</label></td>"; + + $body .= "<td>"; + foreach ( get_web_mails() as $provider => $details ) + { + if ( $oi_provider == $provider ) { + $body .= "<input type='radio' name='oi_provider' value='{$provider}' checked='checked'> {$details}</input><br />"; + } else { + $body .= "<input type='radio' name='oi_provider' value='{$provider}'> {$details}</input><br />"; + } + } + $body .= "<br />"; + foreach ( get_social_networks() as $provider => $details ) + { + if ( $oi_provider == $provider ) { + $body .= "<input type='radio' name='oi_provider' value='{$provider}' checked='checked'> {$details}</input><br />"; + } else { + $body .= "<input type='radio' name='oi_provider' value='{$provider}'> {$details}</input><br />"; + } + } + $body .= "<br /"; + $body .= "</td>"; + + $body .= "</tr>"; + + $body .= "<tr>"; + $body .= "<td><label>".elgg_echo('contact_importer:username')."</label></td>"; + $body .= "<td><input type='text' name='oi_username' value='{$oi_username}' / ></td>"; + $body .= "</tr>"; + + $body .= "<tr>"; + $body .= "<td><label>".elgg_echo('contact_importer:password')."</label></td>"; + $body .= "<td><input type='password' name='oi_password' / ></td>"; + $body .= "<td style='color:red;font-size:11px'>".elgg_echo('contact_importer:password:disclaimer').".</td>"; + $body .= "</tr>"; + + $body .= "</table>"; + + $body .= "<input type='submit' name='submit' value='".elgg_echo('contact_importer:submit')."' />"; + $body .= "<input type='hidden' name='oi_step' value='Inputs' />"; + + $body .= "</form>"; + + return $body; + } + + function echo_OpenInviter_Invite_form ($oi_provider, $oi_provider_name, $oi_username, $oi_contacts, $oi_session_id) { + + $body .= + "<script type='text/javascript'> + function selectAll(count,which) + { + for( z=1; z<=count; z++ ) + { + var check_obj = document.getElementById('check_'+z) + if ( check_obj ) { + check_obj.checked = which; + } + } + } + </script>"; + + $body .= "<form action='' method='POST' name='OpenInviter_Invite'>"; + if (count($oi_contacts)==0) + { + $body .= "<table class='contactImportTable'>"; + $body .= "<H2>".sprintf(elgg_echo('contact_importer:contacts'),$oi_provider_name)."</H2>"; + $body .= "<tr class='contactImportTableOddRow'>"; + $body .= "<td align='center' style='padding:20px;' colspan='".($plugType=='email'? "3":"2")."'>"; + $body .= "<label class='OpenInviter_Error'>".elgg_echo('contact_importer:nocontacts')."</label>"; + $body .= "</td>"; + $body .= "</tr>"; + $body .= "</table>"; + } + else + { + $body .= "<input type='submit' name='send' value='".elgg_echo('contact_importer:send_invites')."' class='thButton'>" . "  "; + $body .= "<H2>".sprintf(elgg_echo('contact_importer:contacts2'),$oi_provider_name,count($oi_contacts))."</H2>"; + $body .= "<a href='javascript:none(0)' onclick='selectAll(".count($oi_contacts).",true)'>".elgg_echo('contact_importer:select_all')."</a>" . "  "; + $body .= "<a href='javascript:none(0)' onclick='selectAll(".count($oi_contacts).",false)'>".elgg_echo('contact_importer:unselect_all')."</a>"; + $body .= "<table class='contactImportTable'>"; + $body .= "<tr class='contactImportTableDesc'>"; + $body .= "<td style='font-weight:bold'>".elgg_echo('contact_importer:invite')."</td>"; + $body .= "<td style='font-weight:bold'>".elgg_echo('contact_importer:name')."</td>".($plugType == 'email' ?"<td style='font-weight:bold'>E-mail</td>":"")."</tr>"; + $odd=true;$counter=0; + foreach ($oi_contacts as $email=>$name) + { + $counter++; + if ($odd) { + $class='contactImportTableOddRow'; + } else { + $class='contactImportTableEvenRow'; + } + $body .= "<tr class='{$class}'>"; + $body .= "<td><input name='check_{$counter}' id='check_{$counter}' value='{$counter}' type='checkbox' class='thCheckbox' checked>"; + $body .= "<input type='hidden' name='email_{$counter}' value='{$email}'>"; + $body .= "<input type='hidden' name='name_{$counter}' value='{$name}'>"; + $body .= "</td><td>{$name}</td>".($plugType == 'email' ?"<td>{$email}</td>":"")."</tr>"; + $odd=!$odd; + } + $body .= "</table>"; + $body .= "<a href='javascript:none(0)' onclick='selectAll(".count($oi_contacts).",true)'>".elgg_echo('contact_importer:select_all')."</a>" . "  "; + $body .= "<a href='javascript:none(0)' onclick='selectAll(".count($oi_contacts).",false)'>".elgg_echo('contact_importer:unselect_all')."</a><br />"; + $body .= "<input type='submit' name='send' value='".elgg_echo('contact_importer:send_invites')."' class='thButton'>" . "  "; + + $body .= "<input type='hidden' name='oi_step' value='Invite' />"; + $body .= "<input type='hidden' name='oi_provider' value='{$oi_provider}'>"; + $body .= "<input type='hidden' name='oi_username' value='{$oi_username}'>"; + $body .= "<input type='hidden' name='oi_session_id' value='{$oi_session_id}'>"; + } + $body .= "</form>"; + + return $body; + } + + function ers($ers) + { + if (!empty($ers)) + { + $contents="<table cellspacing='0' cellpadding='0' style='border:1px solid red;' align='center' class='tbErrorMsgGrad'><tr><td valign='middle' style='padding:3px' valign='middle' class='tbErrorMsg'><img src='/images/ers.gif'></td><td valign='middle' style='color:red;padding:5px;'>"; + foreach ($ers as $key=>$error) + $contents.="{$error}<br >"; + $contents.="</td></tr></table><br >"; + return $contents; + } + } + + function oks($oks) + { + if (!empty($oks)) + { + $contents="<table border='0' cellspacing='0' cellpadding='10' style='border:1px solid #5897FE;' align='center' class='tbInfoMsgGrad'><tr><td valign='middle' valign='middle' class='tbInfoMsg'><img src='/images/oks.gif' ></td><td valign='middle' style='color:#5897FE;padding:5px;'> "; + foreach ($oks as $key=>$msg) + $contents.="{$msg}<br >"; + $contents.="</td></tr></table><br >"; + return $contents; + } + } + + if ( !isset($_POST['oi_step']) ) { + + $body .= echo_OpenInviter_Inputs_form($oi_services, $oi_provider, $oi_username); + + } else if ( $_POST['oi_step'] == "Inputs" ) { + + $ers=array();$oks=array();$import_ok=false;$done=false; + $inviter->startPlugin($oi_provider); + $internal=$inviter->getInternalError(); + if ($internal) + { + $body .= echo_OpenInviter_Inputs_form($oi_services, $oi_provider, $oi_username); + $body .= "<label class='OpenInviter_Error'>" . $internal . "</label>"; + } + elseif (!$inviter->login($oi_username,$oi_password)) + { + $body .= echo_OpenInviter_Inputs_form($oi_services, $oi_provider, $oi_username); + $internal=$inviter->getInternalError(); + if ( $internal ) + $body .= "<label class='OpenInviter_Error'>" . $internal . "</label>"; + else + $body .= "<label class='OpenInviter_Error'>" . elgg_echo('contact_importer:login_failed') . "</label>"; + } + elseif (false===$contacts=$inviter->getMyContacts()) + { + $body .= echo_OpenInviter_Inputs_form($oi_services, $oi_provider, $oi_username); + $body .= "<label class='OpenInviter_Error'>" . elgg_echo('contact_importer:contact_err') . "</label>"; + } + else + { + // success -> show the contacts + $body .= echo_OpenInviter_Invite_form ($oi_provider, $oi_provider_name, $oi_username, $contacts, $inviter->plugin->getSessionID()); + } + + } else if ( $_POST['oi_step'] == "Invite" ) { + $inviter->startPlugin($oi_provider); + $internal=$inviter->getInternalError(); + if ($internal) + { + $body .= echo_OpenInviter_Inputs_form($oi_services, $oi_provider, $oi_username); + $body .= "<label class='OpenInviter_Error'>" . $internal . "</label>"; + } + else + { + $selected_contacts=array(); $invitee_list=""; + foreach ($_POST as $key=>$val) { + if (strpos($key,'check_')!==false) { + $selected_contacts[$_POST['email_'.$val]]=$_POST['name_'.$val]; + $invitee_list .= " - " . $_POST['name_'.$val] . "<br />"; + } elseif (strpos($key,'email_')!==false) { + $temp=explode('_',$key);$counter=$temp[1]; + if (is_numeric($temp[1])) $contacts[$val]=$_POST['name_'.$temp[1]]; + } + } + if (count($selected_contacts)==0) { + $body .= "<label class='OpenInviter_Error'>" . elgg_echo('contact_importer:contacts_sel_err') . "</label>"; + } else { + + // Compose the message + $message['subject'] = + sprintf( + elgg_echo ('contact_importer:email:subject'), + $CONFIG->site->name + ); + $message['body'] = + sprintf( + elgg_echo ('contact_importer:email:mailbody'), + $CONFIG->site->name, + $_SESSION['user']->name, + $CONFIG->wwwroot + ); + + $sendMessage=$inviter->sendMessage($oi_session_id,$message,$selected_contacts); + $inviter->logout(); + + if ($sendMessage===-1) + { + $message_subject=$_SESSION['user']->name.": ".$message['subject']; + $message_body=$message['body']; + $headers="From: {$_SESSION['user']->email}"; + foreach ($selected_contacts as $email=>$name) { + mail($email,$message_subject,$message_body,$headers); + } + $body .= "<label class='OpenInviter_Info'>" . elgg_echo('contact_importer:send_success') . "<br />" . $invitee_list . "</label>"; + } + elseif ($sendMessage===false) + { + $internal=$inviter->getInternalError(); + if ( $internal ) { + $body .= "<label class='OpenInviter_Error'>" . $internal . "</label>"; + } else { + $body .= "<label class='OpenInviter_Error'>" . elgg_echo('contact_importer:send_err') . "</label>"; + } + } + else + { + $body .= "<label class='OpenInviter_Info'>" . elgg_echo('contact_importer:send_success') . "<br />" . $invitee_list . "</label>"; + } + } + } + } + + $body .= "</div>"; + + $body = elgg_view_layout('two_column_left_sidebar','',$body); + + // Finally draw the page + page_draw(elgg_echo('contact_importer:title'), $body); +?> diff --git a/plugins/contact_importer/languages/en.php b/plugins/contact_importer/languages/en.php new file mode 100755 index 00000000..bd1f1844 --- /dev/null +++ b/plugins/contact_importer/languages/en.php @@ -0,0 +1,47 @@ +<?php + + /** + * Contact Importer Plugin (using OpenInviter) + * + * @package ElggContactImporter + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Prashant Juvekar + * @copyright SocialTrak, 2009 + * @link http://www.socialtrak.com + */ + + $english = array( + + 'contact_importer:plugin:name' => 'Import Contacts', + 'contact_importer:title' => 'Import Contacts', + + 'contact_importer:email:subject' => 'Invitation to join %s', + 'contact_importer:email:mailbody' => ' +You have been invited to join %s by %s. +To join, click the following link: + + %s', + + 'contact_importer:password:disclaimer' => "This password will not be stored by us", + 'contact_importer:submit' => "Submit", + 'contact_importer:choose_provider' => "Choose a Provider", + 'contact_importer:username' => "Enter Username", + 'contact_importer:password' => "Enter Password", + 'contact_importer:contacts' => "Your %s contacts", + 'contact_importer:contacts2' => "Your %s contacts (Found %s)", + 'contact_importer:nocontacts' => "You do not have any contacts in your address book.", + 'contact_importer:send_invites' => "Send Invites", + 'contact_importer:select_all' => "Select All", + 'contact_importer:unselect_all' => "Unselect All", + 'contact_importer:invite' => "Invite?", + 'contact_importer:name' => "Name", + 'contact_importer:login_failed' => "Login failed. Please check the email and password you have provided and try again.", + 'contact_importer:contacts_err' => "Unable to get contacts.", + 'contact_importer:contacts_sel_err' => "You did not select any contacts to invite.", + 'contact_importer:send_success' => "Invitation emails were sent successfully to the following:", + 'contact_importer:send_err' => "There were errors while sending your invites.<br>Please try again later!", + + ); + + add_translation("en",$english); +?> \ No newline at end of file diff --git a/plugins/contact_importer/manifest.xml b/plugins/contact_importer/manifest.xml new file mode 100755 index 00000000..e54fe8f3 --- /dev/null +++ b/plugins/contact_importer/manifest.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin_manifest> +<field key="author" value="Prashant Juvekar" /> +<field key="version" value="0.5" /> +<field key="description" value="Import from facebook, twitter, gmail, etc." /> +<field key="website" value="http://www.socialtrak.com/" /> +<field key="copyright" value="(C) Prashant Juvekar 2009" /> +<field key="licence" value="GNU Public License version 2" /> +</plugin_manifest> diff --git a/plugins/contact_importer/start.php b/plugins/contact_importer/start.php new file mode 100755 index 00000000..dcdc8156 --- /dev/null +++ b/plugins/contact_importer/start.php @@ -0,0 +1,47 @@ +<?php + + /** + * Contact Importer Plugin (using OpenInviter) + * + * @package ElggContactImporter + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Prashant Juvekar + * @copyright SocialTrak, 2009 + * @link http://www.socialtrak.com + */ + + // Get config + global $CONFIG; + + /** + * Initialisation function + */ + + function contact_importer_init() { + + // Get config + global $CONFIG; + + // Load the language file + register_translations($CONFIG->pluginspath . "contact_importer/languages/"); + + // Load menu for logged in users + if ( isloggedin() ) { + // Menu options + global $CONFIG; + if (get_context() == "friends" || + get_context() == "friendsof" || + get_context() == "collections") { + add_submenu_item(elgg_echo('contact_importer:plugin:name'),$CONFIG->wwwroot."mod/contact_importer/import.php",'import'); + } + } + + // Extend CSS + extend_view('css', 'contact_importer/css'); + + } + + // Make sure init is called on initialisation + register_elgg_event_handler('pagesetup','system','contact_importer_init',1000); + +?> \ No newline at end of file diff --git a/plugins/friend_request/actions/approve.php b/plugins/friend_request/actions/approve.php new file mode 100755 index 00000000..1dce1564 --- /dev/null +++ b/plugins/friend_request/actions/approve.php @@ -0,0 +1,46 @@ +<?php + /** + * Friend request plugin + * Approve a friend request and make connection both ways + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + action_gatekeeper(); + gatekeeper(); + + $friend_guid = (int) get_input("guid"); + $friend = get_user($friend_guid); + + if(!empty($friend)){ + $user = get_loggedin_user(); + + if(remove_entity_relationship($friend->guid, 'friendrequest', $user->guid)) { + global $CONFIG; + + if(isset($CONFIG->events['create']['friend'])) { + $oldEventHander = $CONFIG->events['create']['friend']; + $CONFIG->events['create']['friend'] = array(); //Removes any event handlers + } + + $user->addFriend($friend->guid); + $friend->addFriend($user->guid); //Friends mean reciprical... + + if(isset($CONFIG->events['create']['friend'])) { + $CONFIG->events['create']['friend'] = $oldEventHander; + } + + system_message(sprintf(elgg_echo('friend_request:approve:successful'), $friend->name)); + // add to river + add_to_river('friends/river/create', 'friend', $user->guid, $friend->guid); + } else { + register_error(sprintf(elgg_echo('friend_request:approve:fail'), $friend->name)); + } + } + + forward($_SERVER['HTTP_REFERER']); +?> \ No newline at end of file diff --git a/plugins/friend_request/actions/decline.php b/plugins/friend_request/actions/decline.php new file mode 100755 index 00000000..51ca7fb0 --- /dev/null +++ b/plugins/friend_request/actions/decline.php @@ -0,0 +1,35 @@ +<?php + /** + * Friend request plugin + * Decline a friend request and notify requester + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + action_gatekeeper(); + gatekeeper(); + + $friend_guid = (int) get_input("guid"); + $friend = get_user($friend_guid); + + if(!empty($friend)){ + $user = get_loggedin_user(); + + if(remove_entity_relationship($friend->guid, 'friendrequest', $user->guid)) { + $subject = sprintf(elgg_echo("friend_request:decline:subject"), $user->name); + $message = sprintf(elgg_echo("friend_request:decline:message"), $friend->name, $user->name); + + notify_user($friend->guid, $user->guid, $subject, $message); + + system_message(elgg_echo("friend_request:decline:success")); + } else { + system_message(elgg_echo("friend_request:decline:fail")); + } + } + + forward($_SERVER['HTTP_REFERER']); +?> \ No newline at end of file diff --git a/plugins/friend_request/actions/friends/add.php b/plugins/friend_request/actions/friends/add.php new file mode 100755 index 00000000..8bda0afc --- /dev/null +++ b/plugins/friend_request/actions/friends/add.php @@ -0,0 +1,92 @@ +<?php + /** + * Friend request plugin + * This action code is based on the regular friend/add action but with a different relationship type + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + //Ensure we're logged in + gatekeeper(); + + //Get our data + $friend_guid = (int) get_input('friend'); + $friend = get_user($friend_guid); + $user_guid = get_loggedin_userid(); + $user = get_loggedin_user(); + + $errors = false; + + //Now we need to attempt to create the relationship + if(empty($user) || empty($friend)) { + $errors = true; + register_error(elgg_echo("friend_request:add:failure")); + } else { + //New for v1.1 - If the other user is already a friend (fan) of this user we should auto-approve the friend request... + if(check_entity_relationship($friend_guid, "friend", $user_guid)) { + try { + if(isset($CONFIG->events['create']['friend'])) { + $oldEventHander = $CONFIG->events['create']['friend']; + $CONFIG->events['create']['friend'] = array(); //Removes any event handlers + } + + $user->addFriend($friend_guid); + system_message(sprintf(elgg_echo("friends:add:successful"),$friend->name)); + + if(isset($CONFIG->events['create']['friend'])) { + $CONFIG->events['create']['friend'] = $oldEventHander; + } + + forward($_SERVER['HTTP_REFERER']); + } catch (Exception $e) { + register_error(sprintf(elgg_echo("friends:add:failure"),$friend->name)); + $errors = true; + } + } elseif(check_entity_relationship($friend_guid, "friendrequest", $user_guid)){ + // Check if your potential friend already invited you, if so make friends + if(remove_entity_relationship($friend_guid, 'friendrequest', $user_guid)){ + if(isset($CONFIG->events['create']['friend'])) { + $oldEventHander = $CONFIG->events['create']['friend']; + $CONFIG->events['create']['friend'] = array(); //Removes any event handlers + } + + $user->addFriend($friend->guid); + $friend->addFriend($user->guid); //Friends mean reciprical... + + if(isset($CONFIG->events['create']['friend'])) { + $CONFIG->events['create']['friend'] = $oldEventHander; + } + + system_message(sprintf(elgg_echo('friend_request:approve:successful'), $friend->name)); + // add to river + add_to_river('friends/river/create', 'friend', $user->guid, $friend->guid); + + forward($_SERVER['HTTP_REFERER']); + } else { + register_error(sprintf(elgg_echo('friend_request:approve:fail'), $friend->name)); + } + } else { + try { + $result = add_entity_relationship($user_guid, "friendrequest", $friend_guid); + if($result == false) { + $errors = true; + register_error(sprintf(elgg_echo("friend_request:add:exists"),$friend->name)); + } + } catch(Exception $e) { //register_error calls insert_data which CAN raise Exceptions. + $errors = true; + register_error(sprintf(elgg_echo("friend_request:add:exists"),$friend->name)); + } + } + } + + if(!$errors) { + system_message(sprintf(elgg_echo("friend_request:add:successful"),$friend->name)); + } + + forward($_SERVER['HTTP_REFERER']); + +?> \ No newline at end of file diff --git a/plugins/friend_request/actions/friends/removefriend.php b/plugins/friend_request/actions/friends/removefriend.php new file mode 100755 index 00000000..7e5cb54d --- /dev/null +++ b/plugins/friend_request/actions/friends/removefriend.php @@ -0,0 +1,48 @@ +<?php + /** + * Friend request plugin + * Remove friend connection on both sides + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + // Ensure we are logged in + gatekeeper(); + + // Get the GUID of the user to friend + $friend_guid = (int) get_input('friend'); + $friend = get_user($friend_guid); + $errors = false; + + // Get the user + if (!empty($friend)) { + $user = get_loggedin_user(); + + try{ + $user->removeFriend($friend_guid); + + try { + //V1.1 - Old relationships might not have the 2 as friends... + $friend->removeFriend($user->guid); + }catch(Exception $e) { + // do nothing + } + } catch (Exception $e) { + register_error(sprintf(elgg_echo("friends:remove:failure"),$friend->name)); + $errors = true; + } + } else { + register_error(sprintf(elgg_echo("friends:remove:failure"),$friend_guid)); + $errors = true; + } + + if(!$errors) { + system_message(sprintf(elgg_echo("friends:remove:successful"),$friend->name)); + } + + forward($_SERVER["HTTP_REFERER"]); +?> \ No newline at end of file diff --git a/plugins/friend_request/actions/revoke.php b/plugins/friend_request/actions/revoke.php new file mode 100755 index 00000000..1ba1a11c --- /dev/null +++ b/plugins/friend_request/actions/revoke.php @@ -0,0 +1,30 @@ +<?php + /** + * Friend request plugin + * Revoke a friend request + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + action_gatekeeper(); + gatekeeper(); + + $friend_guid = (int) get_input("guid"); + $friend = get_user($friend_guid); + + if(!empty($friend)){ + $user = get_loggedin_user(); + + if(remove_entity_relationship($user->guid, 'friendrequest', $friend->guid)) { + system_message(elgg_echo("friend_request:revoke:success")); + } else { + system_message(elgg_echo("friend_request:revoke:fail")); + } + } + + forward($_SERVER['HTTP_REFERER']); +?> \ No newline at end of file diff --git a/plugins/friend_request/graphics/icons/friendrequest.png b/plugins/friend_request/graphics/icons/friendrequest.png new file mode 100755 index 0000000000000000000000000000000000000000..a2e6b50af07a623c329c71dee9802b9dc594a031 GIT binary patch literal 685 zcmV;e0#f~nP)<h;3K|Lk000e1NJLTq000mG001Be1^@s68;SVL00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9a%BKeVQFr3 zE>1;MAa*k@Gd8K`;w1n80rE*iK~zXfos`Q;!$25?+r2CIzKL(3-E`R}@Co`X5!8j$ zLa8($*o_Mzy`?wO#>C)4p|f-;2(J9?ndBcQw`pnN(9Gq0=by=Bsuk@we6&b!^YiK1 zMYX6u)dzDljTMe#ak~tx0GPlge_)X=?l(d(2$T5G^tOFYgt5Z_uUp9KO2T&n1SV^# zvi-8v@`l8?y(a)B7MrIn33$4{EPO+1BOf|(xk^Y*%-&*XHZuh&(v%o8$$;oe9}WN3 zl4U~noh5~2A%qmn^cyPy{R3bY&J(S#xBrPjH*zw}U&pB`;-xV_tluSsl}%>A_erJ_ z1@Hm_M7UE~kq-Dgst|+<SZXPSfaksf@DhH`D}?miW|mffiZYw10n%?_U|CcqUW)NG z0@v^NsYpBT0ya-36M{ygkrcN9H9|0fO^)M`F77u%FbGo=MM^;s5DQ}m0es&l&+{aF zCjgW6RJ2#C6)l%bn$2eW0bpXWd9heXK(E&`Z)B&_k>#?G%;x!gzTbU-6qwkUNjBdH zwr$HYp?141g=GCGZ#El(a`yquNb7dH#`^%~dcB^ngaJ4QfUx)*;A93g8jW-%3<$$e z9wcleD$)V9T8$u7z*0*o0=TZ5yAPVpCLuldRhCtNin5!i0n*=BtJR`1neKx>*$VAu TfIu?Y00000NkvXXu0mjf5(gXa literal 0 HcmV?d00001 diff --git a/plugins/friend_request/index.php b/plugins/friend_request/index.php new file mode 100755 index 00000000..799e671c --- /dev/null +++ b/plugins/friend_request/index.php @@ -0,0 +1,43 @@ +<?php + /** + * Friend request plugin + * List all the requests (sent and received) + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.1 + */ + + gatekeeper(); + + $user = get_loggedin_user(); + + // set the correct context and page owner + set_context("friends"); + set_page_owner($user->guid); + + // fix to show collections links + collections_submenu_items(); + + // Get all the data + $received_count = get_entities_from_relationship("friendrequest", $user->guid, true, "user", "", 0, "", 0, 0, true); + $received_requests = get_entities_from_relationship("friendrequest", $user->guid, true, "user", "", 0, "", $received_count); + + $sent_count = get_entities_from_relationship("friendrequest", $user->guid, false, "user", "", 0, "", 0, 0, true); + $sent_requests = get_entities_from_relationship("friendrequest", $user->guid, false, "user", "", 0, "", $sent_count); + + // Get page elements + $title = elgg_view_title(elgg_echo('friend_request:title')); + + $received = elgg_view("friend_request/received", array("entities" => $received_requests, "request_count" => $received_count)); + $sent = elgg_view("friend_request/sent", array("entities" => $sent_requests, "request_count" => $sent_count)); + + // Build page + $page_body = $title . $received . $sent; + + // Draw page + page_draw(elgg_echo("friend_request:title"), elgg_view_layout('two_column_left_sidebar', '', $page_body)); + +?> \ No newline at end of file diff --git a/plugins/friend_request/languages/en.php b/plugins/friend_request/languages/en.php new file mode 100755 index 00000000..60eb1a25 --- /dev/null +++ b/plugins/friend_request/languages/en.php @@ -0,0 +1,54 @@ +<?php + $english = array( + 'friend_request' => "Friend Request", + 'friend_request:menu' => "Friend Requests", + 'friend_request:title' => "Friend Requests", + + 'friend_request:new' => "New friend request", + + 'friend_request:newfriend:subject' => "%s wants to be your friend!", + 'friend_request:newfriend:body' => "%s wants to be your friend! But they are waiting for you to approve the request...so login now so you can approve the request! + +You can view your pending friend requests at (Make sure you are logged into the website before clicking on the following link otherwise you will be redirected to the login page.): + +%s + +(You cannot reply to this email.)", + + // Actions + // Add request + 'friend_request:add:failure' => "Sorry, because of a system error we were unable to complete your request. Please try again.", + 'friend_request:add:successful' => "You have requested to be friends with %s. They must approve your request before they will show on your friends list.", + 'friend_request:add:exists' => "You've already requested to be friends with %s.", + + // Approve request + 'friend_request:approve' => "Approve", + 'friend_request:approve:successful' => "%s is now a friend", + 'friend_request:approve:fail' => "Error while creating friend relation with %s", + + // Decline request + 'friend_request:decline' => "Decline", + 'friend_request:decline:subject' => "%s has declined your friend request", + 'friend_request:decline:message' => "Dear %s, + +%s has declined your request to become a friend.", + 'friend_request:decline:success' => "Friend request succesfully declined", + 'friend_request:decline:fail' => "Error while declining Friend request, please try again", + + // Revoke request + 'friend_request:revoke' => "Revoke", + 'friend_request:revoke:success' => "Friend request succesfully revoked", + 'friend_request:revoke:fail' => "Error while revoking Friend request, please try again", + + // Views + // Received + 'friend_request:received:title' => "Received Friend requests", + 'friend_request:received:none' => "No requests pending your approval", + + // Sent + 'friend_request:sent:title' => "Sent Friend requests", + 'friend_request:sent:none' => "No sent requests pending approval", + ); + + add_translation("en", $english); +?> \ No newline at end of file diff --git a/plugins/friend_request/manifest.xml b/plugins/friend_request/manifest.xml new file mode 100755 index 00000000..40cf8789 --- /dev/null +++ b/plugins/friend_request/manifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin_manifest> + <field key="author" value="ColdTrick IT Solutions" /> + <field key="version" value="2.1" /> + <field key="description" value="Let users confirm friend requests. Make all friend requests reciprocal. Based on friend_request by Bosssumon and Zac Hopkinson" /> + <field key="website" value="http://www.coldtrick.com" /> + <field key="copyright" value="(C) ColdTrick 2009" /> + <field key="licence" value="GNU Public License version 2" /> + <field key="elgg_version" value="2009031301" /> +</plugin_manifest> +<!-- +================= +Version History +================= +2.1: + - added: CSS fix to hide friendsof on profile and user pulldown menu + - added: friends menu no longer showing friendsof + - fixed: collections links now showing + - changed: menu title language handling + - changed: CSS for topbar + +2.0: + - added: menu options in friends and messages + - added: option to revoke a request + - added: listing of sent requests + - changed: listing of received friend requests + - changed: Elgg topbar icon + +1.5: + - latest release by Bosssumon and Zac Hopkinson +--> \ No newline at end of file diff --git a/plugins/friend_request/start.php b/plugins/friend_request/start.php new file mode 100755 index 00000000..2519d0aa --- /dev/null +++ b/plugins/friend_request/start.php @@ -0,0 +1,125 @@ +<?php + /** + * Friend request plugin + * Requires a friend to confirm your request to become a connection + * + * Original design by Bosssumon and Zac Hopkinson + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.1 + */ + + function friend_request_init() { + global $CONFIG; + + //Extend CSS + extend_view('css', 'friend_request/css'); + + if(isloggedin()){ + //Extend topbar to add our link if needed + extend_view('elgg_topbar/extend', 'friend_request/topbar'); + } + + //This overwrites the original friend requesting stuff. + register_action("friends/add", false, $CONFIG->pluginspath . "friend_request/actions/friends/add.php", false); + + //We need to override the friend remove action to remove the relationship we created + register_action("friends/remove", false, $CONFIG->pluginspath . "friend_request/actions/friends/removefriend.php"); + + //This will let uesrs view their friend requests + register_page_handler('friend_request', 'friend_request_page_handler'); + } + + function friend_request_event_create_friend($event, $object_type, $object) { + global $CONFIG; + + if (($object instanceof ElggRelationship) && ($event == 'create') && ($object_type == 'friend') ) { + //We don't want anything happening here... (no email/etc) + + //Returning false will interrupt the rest of the chain. + //The normal handler for the create friend event has a priority of 500 so it will never be called. + return false; + } + return true; //Shouldn't get here... + } + + //Allow us to send an notification email: + function friend_request_event_create_friendrequest($event, $object_type, $object) { + global $CONFIG; + + if (($object instanceof ElggRelationship) && ($event == 'create') && ($object_type == 'friendrequest')) { + $user_one = get_entity($object->guid_one); + $user_two = get_entity($object->guid_two); + + $view_friends_url = $CONFIG->wwwroot . "pg/friend_request"; + + // Notify target user + $subject = sprintf(elgg_echo('friend_request:newfriend:subject'), $user_one->name); + $message = sprintf(elgg_echo("friend_request:newfriend:body"), $user_one->name, $view_friends_url); + + return notify_user($object->guid_two, $object->guid_one, $subject, $message); + } + } + + function friend_request_page_handler($page) { + global $CONFIG; + + include($CONFIG->pluginspath . "friend_request/index.php"); + } + + function friend_request_pagesetup(){ + global $CONFIG; + + // Remove link to friendsof + if(!empty($CONFIG->submenu["a"])){ + $submenu_links = &$CONFIG->submenu["a"]; + $lang_friendsof = elgg_echo("friends:of"); + + foreach($submenu_links as $index => $object){ + if($object->name == $lang_friendsof){ + unset($submenu_links[$index]); + break; + } + } + } + + // Show menu link in the correct context + if(isloggedin() && + (get_context() == "friends" || + get_context() == "friendsof" || + get_context() == "collections" || + get_context() == "messages") + ){ + $count = get_entities_from_relationship('friendrequest', get_loggedin_user()->guid, true, "", "", 0, "", 0, 0, true); + + if(!empty($count)){ + $extra = " [" . $count . "]"; + } else { + $extra = ""; + } + + add_submenu_item(elgg_echo("friend_request:menu") . $extra, $CONFIG->wwwroot . "pg/friend_request/", "b"); + } + + } + + // Default event handlers + register_elgg_event_handler('init', 'system', 'friend_request_init', 100); + register_elgg_event_handler('pagesetup', 'system', 'friend_request_pagesetup'); + + //Our friendrequest handlers... + register_action("friend_request/approve", false, $CONFIG->pluginspath . "friend_request/actions/approve.php"); + register_action("friend_request/decline", false, $CONFIG->pluginspath . "friend_request/actions/decline.php"); + register_action("friend_request/revoke", false, $CONFIG->pluginspath . "friend_request/actions/revoke.php"); + + //Regular Elgg engine sends out an email via an event. The 400 priority will let us run first. + //Then we return false to stop the event chain. The normal event handler will never get to run. + register_elgg_event_handler('create', 'friend', 'friend_request_event_create_friend', 400); + + //Handle our add action event: + register_elgg_event_handler('create', 'friendrequest', 'friend_request_event_create_friendrequest'); + +?> \ No newline at end of file diff --git a/plugins/friend_request/views/default/friend_request/css.php b/plugins/friend_request/views/default/friend_request/css.php new file mode 100755 index 00000000..dc89b4d9 --- /dev/null +++ b/plugins/friend_request/views/default/friend_request/css.php @@ -0,0 +1,35 @@ +<?php + /** + * Friend request plugin + * CSS extensions + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.1 + */ +?> +.new_friendrequests { + background: transparent url(<?php echo $vars['url']; ?>mod/friend_request/graphics/icons/friendrequest.png) no-repeat left -16px; + padding: 0 0 0 18px; + margin: 0 5px 0 5px; +} + +.new_friendrequests:hover { + text-decoration: none; + background-position: left top; +} + +.friend_request { + margin: 0 0 5px 0; +} + +.friend_request td { + padding: 0 0 0 3px; +} + +/* hide some links on profile */ +.user_menu_friends_of { + display: none; +} \ No newline at end of file diff --git a/plugins/friend_request/views/default/friend_request/received.php b/plugins/friend_request/views/default/friend_request/received.php new file mode 100755 index 00000000..fbc31baa --- /dev/null +++ b/plugins/friend_request/views/default/friend_request/received.php @@ -0,0 +1,45 @@ +<?php + /** + * Friend request plugin + * List all received requests + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + $count = $vars["request_count"]; + $entities = $vars["entities"]; + + $content = ""; + + $ts = time(); + $token = generate_action_token($ts); + + if($count > 0){ + foreach($entities as $entity){ + $content .= "<table class='friend_request'>\n"; + $content .= "<tr>\n"; + $content .= "<td rowspan='2'>" . elgg_view("profile/icon", array("entity" => $entity, "size" => "small")) . "</td>\n"; + $content .= "<td><a href='" . $entity->getURL() . "' title='" . $entity->name . "'>" . $entity->name . "</a></td>\n"; + $content .= "</tr>\n"; + $content .= "<tr>\n"; + $content .= "<td>"; + $content .= "<a href='" . $CONFIG->wwwroot . "action/friend_request/approve?guid=" . $entity->guid . "&__elgg_ts=" . $ts ."&__elgg_token=" . $token . "' title='" . elgg_echo("friend_request:approve") . "'>" . elgg_echo("friend_request:approve") . "</a>"; + $content .= " | "; + $content .= "<a href='" . $CONFIG->wwwroot . "action/friend_request/decline?guid=" . $entity->guid . "&__elgg_ts=" . $ts ."&__elgg_token=" . $token . "' title='" . elgg_echo("friend_request:decline") . "'>" . elgg_echo("friend_request:decline") . "</a>"; + $content .= "</td>\n"; + $content .= "</tr>\n"; + $content .= "</table>\n"; + } + } else { + $content = elgg_echo("friend_request:received:none"); + } + +?> +<div class="contentWrapper"> + <h3 class="settings"><?php echo elgg_echo("friend_request:received:title"); ?></h3> + <?php echo $content; ?> +</div> \ No newline at end of file diff --git a/plugins/friend_request/views/default/friend_request/sent.php b/plugins/friend_request/views/default/friend_request/sent.php new file mode 100755 index 00000000..944d1f1f --- /dev/null +++ b/plugins/friend_request/views/default/friend_request/sent.php @@ -0,0 +1,43 @@ +<?php + /** + * Friend request plugin + * List all sent requests + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + $count = $vars["request_count"]; + $entities = $vars["entities"]; + + $content = ""; + + $ts = time(); + $token = generate_action_token($ts); + + if($count > 0){ + foreach($entities as $entity){ + $content .= "<table class='friend_request'>\n"; + $content .= "<tr>\n"; + $content .= "<td rowspan='2'>" . elgg_view("profile/icon", array("entity" => $entity, "size" => "small")) . "</td>\n"; + $content .= "<td><a href='" . $entity->getURL() . "' title='" . $entity->name . "'>" . $entity->name . "</a></td>\n"; + $content .= "</tr>\n"; + $content .= "<tr>\n"; + $content .= "<td>"; + $content .= "<a href='" . $CONFIG->wwwroot . "action/friend_request/revoke?guid=" . $entity->guid . "&__elgg_ts=" . $ts ."&__elgg_token=" . $token . "' title='" . elgg_echo("friend_request:revoke") . "'>" . elgg_echo("friend_request:revoke") . "</a>"; + $content .= "</td>\n"; + $content .= "</tr>\n"; + $content .= "</table>\n"; + } + } else { + $content = elgg_echo("friend_request:sent:none"); + } + +?> +<div class="contentWrapper"> + <h3 class="settings"><?php echo elgg_echo("friend_request:sent:title"); ?></h3> + <?php echo $content; ?> +</div> \ No newline at end of file diff --git a/plugins/friend_request/views/default/friend_request/topbar.php b/plugins/friend_request/views/default/friend_request/topbar.php new file mode 100755 index 00000000..464aa9f0 --- /dev/null +++ b/plugins/friend_request/views/default/friend_request/topbar.php @@ -0,0 +1,22 @@ +<?php + /** + * Friend request plugin + * Extend the Elgg topbar with link to Friends request, if any + * + * @package friend_request + * @author ColdTrick IT Solutions + * @copyright Coldtrick IT Solutions 2009 + * @link http://www.coldtrick.com/ + * @version 2.0 + */ + + if(isloggedin()){ + $user = get_loggedin_user(); + + $count = get_entities_from_relationship('friendrequest', $user->guid, true, "", "", 0, "", 0, 0, true); + + if(!empty($count)){ + echo "<a href='" . $CONFIG->wwwroot . "pg/friend_request' class='new_friendrequests' title='" . elgg_echo('friend_request:new') . "'>[" . $count . "]</a>"; + } + } +?> \ No newline at end of file diff --git a/plugins/riverfaces/graphics/clock_icon.gif b/plugins/riverfaces/graphics/clock_icon.gif new file mode 100755 index 0000000000000000000000000000000000000000..5dcacfc25bb5e73749534a7a0129c42cde727f94 GIT binary patch literal 1034 zcmeH`+fUMQ0L8yZHoKdZ-Q3Ein=999*0Qpe)=XP#)oSaZ2fMB{^MYipRg>5PMMy}c zGEFXl_@j9Xq68HzMX_a?X*d0mfM{tqO33OIJ@+T{+1YtGZ|7`hdvapz`a{7an2Zww z0*b1VN-1$c<@I81kyw?-FBOY#QIuArd7x4@Icdj>;je8@&!hgamaf-^+S*)Rky5E? zGIe_Zn+F3EpuKqY4W{>~q4B`nnx9)Bld09Wo4r8Q<KAAU>l5(C3)>hP-7vaQ<3P<l z<ArlM6h%pkE8RmQT@xr($^!|hwLN(Qw10tR1oaLW9MJatx=~ml5QroNnt_iKF2Dy+ zP0iDo3<*`&>4o((Oit+R(7U13>atH~-Mm)S`R@DRPtZT$0Q9{BTjOGPCnZ)r8)+EE zT^bE;DD>8>%rt3XMZ5D`zYjg*=mT0t#$#8lOy0Ul{rGLY3wj!5wJn+HsqHU^I>*uB zLF3@(1+!<K;s^|OpLq;A8qF@~hEO7_%s$PQNXm=`qrr_f4{{3251wQhXs>w`dOPmh z(J=}|*AE`&yhtR>;}tiy_n1DQ<qOOoQ16Ce5Y0n)GKM>LNJ|x28EFc+MkEmH%(glQ zETd@sqxUeqgQ^G8GF5g~y3CL2;(1Pqv`BsLk-D)@VeGzHq33fiuvzK(f_yfMm6?`$ zhRqTQh2%f~S|HpviQ&(q{pSA!3F;?|ps=Ls6f;@D3ey~>X9RFb$k`MbGk4zVjPDW4 zuccUcp&KO!7tU$DBHzJeMwJsw;H=04R;#bhDw)a&2;CR-N!}`nKIS5a*=<*w7}KNq zId*PtXbd}Gt;LhPlrwpL;zRG#qqgfCE`=RSh^WqCPLDWBGA)6^()cTDI3XwK_{$+N zm*R#cu9@LUB?(jFNIZASqJ;9Zd${V|5xeA*mhr3Y+l1kJ8nkUklJ=@g0wOcE9OCll tMx}bfZfw(}@aC?|+sWuYK1=?5@_u?%LS+8p&E?@!mn;Y-8~s)P@*Cpqzq$Yb literal 0 HcmV?d00001 diff --git a/plugins/riverfaces/languages/en.php b/plugins/riverfaces/languages/en.php new file mode 100755 index 00000000..2e4bdbb0 --- /dev/null +++ b/plugins/riverfaces/languages/en.php @@ -0,0 +1,16 @@ +<?php +$english = array( + + 'riverfaces:settings:iconsize' => 'User Icon size?', + 'riverfaces:settings:iconsize:medium' => 'Medium', + 'riverfaces:settings:iconsize:small' => 'Small', + 'riverfaces:settings:iconsize:tiny' => 'Tiny', + 'riverfaces:settings:iconsize:topbar' => 'Topbar', + + 'riverfaces:settings:adjustsize' => 'Adjust icon display size?', + + 'riverfaces:settings:showcontextmenu' => 'Show user icon context menu?', +); + +add_translation("en",$english); +?> \ No newline at end of file diff --git a/plugins/riverfaces/languages/es.php b/plugins/riverfaces/languages/es.php new file mode 100755 index 00000000..6b9e09a8 --- /dev/null +++ b/plugins/riverfaces/languages/es.php @@ -0,0 +1,17 @@ +<?php + +$spanish = array( + 'riverfaces:settings:iconsize' => 'Tamaño del icono de usuario?', + 'riverfaces:settings:iconsize:medium' => 'Mediano', + 'riverfaces:settings:iconsize:small' => 'Pequeño', + 'riverfaces:settings:iconsize:tiny' => 'Diminuto', + 'riverfaces:settings:iconsize:topbar' => 'Topbar', + + 'riverfaces:settings:adjustsize' => 'Ajustar el tamaño de icono mostrado?', + + 'riverfaces:settings:showcontextmenu' => 'Mostrar el menu de usuario en el icono?', +); + +add_translation('es', $spanish); + +?> \ No newline at end of file diff --git a/plugins/riverfaces/manifest.xml b/plugins/riverfaces/manifest.xml new file mode 100755 index 00000000..6e73b7c1 --- /dev/null +++ b/plugins/riverfaces/manifest.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin_manifest> + <field key="author" value="Adolfo Mazorra" /> + <field key="version" value="0.3" /> + <field key="description" value="Add user icons to the river activity items." /> + <field key="copyright" value="(C) Adolfo Mazorra 2009" /> + <field key="licence" value="GNU Public License version 2" /> + <field key="elgg_version" value="2009030702" /> +</plugin_manifest> \ No newline at end of file diff --git a/plugins/riverfaces/readme.txt b/plugins/riverfaces/readme.txt new file mode 100755 index 00000000..d8dba808 --- /dev/null +++ b/plugins/riverfaces/readme.txt @@ -0,0 +1,39 @@ +/** + * RiverFaces + * + * @package riverfaces + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Adolfo Mazorra + * @copyright Adolfo Mazorra 2009 + * @version 0.3 + */ + +DESCRIPTION + + This is a little plugin that modifies the river item wrapper and css to show the profile icon + of each user next to the activity (and river) items. + + The size of the icons can be changed in the plugin settings (four sizes available: medium, small, + tiny and topbar) and also there is a settings option to adjust their size to that of the tiny + activity type icon. + + The icons include by default the user context menu, but this can also be changed in the settings. + +INSTALLATION + + To install just extract in the 'mod' folder and enable the plugin. + +CHANGELIST: + v0.3 + - Added small clock next to the time display (idea & icon from the '3 column dashboard' plugin). + - Added option to adjust user icon size to that of the small activity type icon (idea from Alex Tanchoco). + - Added option to remove the user icon context menu. + - Spanish translation included. + + v0.2 + - Added setting parameter to define the user icon size. + - A couple of changes to css. + + v0.1 + - Initial release. + diff --git a/plugins/riverfaces/start.php b/plugins/riverfaces/start.php new file mode 100755 index 00000000..8dd4b9ba --- /dev/null +++ b/plugins/riverfaces/start.php @@ -0,0 +1,18 @@ +<?php + + /** + * RiverFaces + * + * @package riverfaces + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Adolfo Mazorra + * @copyright Adolfo Mazorra 2009 + */ + + function riverfaces_init() { + extend_view('css','riverfaces/css'); + } + + register_elgg_event_handler('init','system','riverfaces_init'); + +?> \ No newline at end of file diff --git a/plugins/riverfaces/views/default/river/item/wrapper.php b/plugins/riverfaces/views/default/river/item/wrapper.php new file mode 100755 index 00000000..69a8d0d3 --- /dev/null +++ b/plugins/riverfaces/views/default/river/item/wrapper.php @@ -0,0 +1,65 @@ +<?php + + /** + * Elgg river item wrapper. + * Wraps all river items. + * + * @package Elgg + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Curverider (modified by Adolfo Mazorra) + * @copyright Curverider Ltd 2008-2009 + * @link http://elgg.com/ + */ + + $size = get_plugin_setting('iconsize', 'riverfaces'); + if (!isset($size) or $size == '') + $size = 'small'; + + $adjustSize = get_plugin_setting('adjustsize', 'riverfaces'); + if ($adjustSize != 'yes') { + $img_size = ''; + $padding_size = $size; + } else { + $img_size = " adjusted_user_icon_size"; + $padding_size = 'topbar'; + } + + $showContextMenu = get_plugin_setting('showContextMenu', 'riverfaces'); + $override = false; + if ($showContextMenu == 'no') { + $override = true; + } + + $user = get_entity($vars['item']->subject_guid); +?> + <div class="river_item"> + <div class="river_item_icon_float<?php echo $img_size;?>"> + <?php + if ($override) { + $link_begin = '<a href="' . $user->getURL() . '" title="' . $user->name . '">'; + $link_end = '</a>'; + } + echo $link_begin . elgg_view("profile/icon", array('entity' => $user,'size' => $size, 'override' => $override)) . $link_end; + ?> + </div> + <div class="river_item_padding_<?php echo $padding_size; ?>"> + <div class="river_<?php echo $vars['item']->type; ?>"> + <div class="river_<?php echo $vars['item']->subtype; ?>"> + <div class="river_<?php echo $vars['item']->action_type; ?>"> + <div class="river_<?php echo $vars['item']->type; ?>_<?php if($vars['item']->subtype) echo $vars['item']->subtype . "_"; ?><?php echo $vars['item']->action_type; ?>"> + <p> + <?php + echo $vars['body']; + ?> + <span class="river_item_time"> + <img src="<?php echo $vars['url']; ?>mod/riverfaces/graphics/clock_icon.gif" width="11px" height="11px" /> + <?php echo friendly_time($vars['item']->posted); ?> + </span> + </p> + </div> + </div> + </div> + </div> + </div> + </div> + <div class="clearfloat"></div> \ No newline at end of file diff --git a/plugins/riverfaces/views/default/riverfaces/css.php b/plugins/riverfaces/views/default/riverfaces/css.php new file mode 100755 index 00000000..77865314 --- /dev/null +++ b/plugins/riverfaces/views/default/riverfaces/css.php @@ -0,0 +1,51 @@ +<?php + /** + * RiverFaces CSS + * + * @package riverfaces + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Adolfo Mazorra + * @copyright Adolfo Mazorra 2009 + */ +?> + +.river_item p { + margin:0; + padding:0 0 0 21px; + line-height:1.1em; + min-height:17px; +} +.river_item { + border-bottom:1px solid #dddddd; + padding:5px 0 5px 0; + margin: 0px 0px 5px 5px; +} +.river_item_padding_medium { + margin-left: 105px; + min-height: 100px; +} +.river_item_padding_small { + margin-left: 45px; + min-height: 40px; +} +.river_item_padding_tiny { + margin-left: 30px; + min-height: 25px; +} +.river_item_padding_topbar { + margin-left: 25px; + min-height: 20px; +} +.river_item_icon_float { + float:left; + margin:0px 4px; +} +.adjusted_user_icon_size img { + width: 18px; + height: 18px; +} +.river_item_time { + display:block; + font-size:90%; + color:#666666; +} diff --git a/plugins/riverfaces/views/default/settings/riverfaces/edit.php b/plugins/riverfaces/views/default/settings/riverfaces/edit.php new file mode 100755 index 00000000..5f5a9621 --- /dev/null +++ b/plugins/riverfaces/views/default/settings/riverfaces/edit.php @@ -0,0 +1,53 @@ +<?php + /** + * Widgetlinks Settings Edit + * + * @package widgetlinks + * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 + * @author Adolfo Mazorra + * @copyright Adolfo Mazorra 2009 + */ +?> + +<table> + <tr> + <td> + <?php echo elgg_echo('riverfaces:settings:iconsize'); ?> + </td> + <td> + <?php + $iconsize = $vars['entity']->iconsize; + if (!isset($iconsize) or $iconsize == '') + $iconsize = 'small'; + ?> + <select name="params[iconsize]"> + <option value="medium" <?php if ($iconsize == 'medium') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('riverfaces:settings:iconsize:medium'); ?></option> + <option value="small" <?php if ($iconsize == 'small') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('riverfaces:settings:iconsize:small'); ?></option> + <option value="tiny" <?php if ($iconsize == 'tiny') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('riverfaces:settings:iconsize:tiny'); ?></option> + <option value="topbar" <?php if ($iconsize == 'topbar') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('riverfaces:settings:iconsize:topbar'); ?></option> + </select> + </td> + </tr> + <tr> + <td> + <?php echo elgg_echo('riverfaces:settings:adjustsize'); ?> + </td> + <td> + <select name="params[adjustsize]"> + <option value="yes" <?php if ($vars['entity']->adjustsize == 'yes') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('option:yes'); ?></option> + <option value="no" <?php if ($vars['entity']->adjustsize != 'yes') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('option:no'); ?></option> + </select> + </td> + </tr> + <tr> + <td> + <?php echo elgg_echo('riverfaces:settings:showcontextmenu'); ?> + </td> + <td> + <select name="params[showContextMenu]"> + <option value="yes" <?php if ($vars['entity']->showContextMenu != 'no') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('option:yes'); ?></option> + <option value="no" <?php if ($vars['entity']->showContextMenu == 'no') echo " selected=\"yes\" "; ?>><?php echo elgg_echo('option:no'); ?></option> + </select> + </td> + </tr> +</table> -- GitLab