<?php
/**
* Include (require) this page if your application wish to use the class Gmailer.
* This page (libgmailer.php) is the definition of 3 classes: GMailer, GMailSnapshot
* and Debugger (deprecated).
*
* @package libgmailer.php
*/
/**
* Constant defined by application author. Set it to true if the class is used as
* a module of an online office app or other situation where PHP Session should NOT
* by destroyed after signing out from Gmail.
*
* @var bool
*/
define("GM_USE_LIB_AS_MODULE", false); // Normal operation
/**#@+
* URL's of Gmail.
* @var string
*/
define("GM_LNK_GMAIL", "https://mail.google.com/mail/");
define("GM_LNK_GMAIL_HTTP", "http://mail.google.com/mail/");
// Changed by Gan; 10 Sept 2005
define("GM_LNK_LOGIN", "https://www.google.com/accounts/ServiceLoginAuth");
// Added by Neerav; 4 Apr 2006
define("GM_LNK_LOGIN_REFER", "https://www.google.com/accounts/ServiceLogin?service=mail&passive=true&rm=false&continue=http%3A%2F%2Fmail.google.com%2Fmail%3Fui%3Dhtml%26zy%3Dl<mpl=yj_blanco<mplcache=2&hl=en");
// Added by Neerav; 5 June 2005
define("GM_LNK_INVITE_REFER", "https://www.google.com/accounts/ServiceLoginBox?service=mail&continue=https%3A%2F%2Fmail.google.com%2Fmail");
// Updated by Neerav; 20 Jan 2007
define("GM_USER_AGENT", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1");
// Added by Neerav; 19 Jan 2007
define("GM_LNK_GMAIL_MOBILE", "http://mail.google.com/mail/x/");
/**
* @deprecated
*/
define("GM_LNK_LOGOUT", "https://mail.google.com/mail/?logout");
define("GM_LNK_REFER", "https://www.google.com/accounts/ServiceLoginBox?service=mail&continue=https%3A%2F%2Fmail.google.com%2Fmail");
define("GM_LNK_CONTACT", "https://mail.google.com/mail/?view=cl&search=contacts&pnl=a");
define("GM_LNK_ATTACHMENT", "https://mail.google.com/mail/?view=att&disp=att");
define("GM_LNK_ATTACHMENT_ZIPPED", "https://mail.google.com/mail/?view=att&disp=zip");
/**#@-*/
/**#@+
* Constants defining Gmail content's type.
* @var int
*/
define("GM_STANDARD", 0x001);
define("GM_LABEL", 0x002);
define("GM_CONVERSATION", 0x004);
define("GM_QUERY", 0x008);
define("GM_CONTACT", 0x010);
define("GM_PREFERENCE", 0x020);
/**#@-*/
/**#@+
* Constants defining Gmail action.
* @var int
*/
/**
* Apply label to conversation
*/
define("GM_ACT_APPLYLABEL", 1);
/**
* Remove label from conversation
*/
define("GM_ACT_REMOVELABEL", 2);
/**
* Star a conversation
*/
define("GM_ACT_STAR", 3);
/**
* Remove a star from (unstar) a conversation
*/
define("GM_ACT_UNSTAR", 4);
/**
* Mark a conversation as spam
*/
define("GM_ACT_SPAM", 5);
/**
* Unmark a conversation from spam
*/
define("GM_ACT_UNSPAM", 6);
/**
* Mark conversation as read
*/
define("GM_ACT_READ", 7);
/**
* Mark conversation as unread
*/
define("GM_ACT_UNREAD", 8);
/**
* Trash a conversation
*/
define("GM_ACT_TRASH", 9);
/**
* Directly delete a conversation
*/
define("GM_ACT_DELFOREVER", 10);
/**
* Archive a conversation
*/
define("GM_ACT_ARCHIVE", 11);
/**
* Move conversation to Inbox
*/
define("GM_ACT_INBOX", 12);
/**
* Move conversation out of Trash
*/
define("GM_ACT_UNTRASH", 13);
/**
* Discard a draft
*/
define("GM_ACT_UNDRAFT", 14);
/**
* Trash individual message.
*/
define("GM_ACT_TRASHMSG", 15);
/**
* Untrash (retrieve from trash) individual message.
* @since 27 Feb 2006
*/
define("GM_ACT_UNTRASHMSG", 18);
/**
* Delete spam, forever.
*/
define("GM_ACT_DELSPAM", 16);
/**
* Delete trash message, forever.
*/
define("GM_ACT_DELTRASHED", 17);
/**
* Deleted trashed messages from the thread forever.
* @since 27 Feb 2006
*/
define("GM_ACT_DELTRASHEDMSGS", 19);
/**#@-*/
/**
* Empty spam, forever.
*/
define("GM_ACT_EMPTYSPAM", 51);
/**
* Empty trash, forever.
*/
define("GM_ACT_EMPTYTRASH", 52);
/**#@+
* Other constants.
*/
define("GM_VER", "0.9.1");
define("GM_COOKIE_KEY", "LIBGMAILER");
define("GM_COOKIE_IK_KEY", "LIBGMAILER_IdKey"); // Added by Neerav; 6 July 2005
define("GM_USE_COOKIE", 0x001);
define("GM_USE_PHPSESSION", 0x002);
if (!defined("GM_COOKIE_TTL")) {
$ttl = 60*60*24*7;
define("GM_COOKIE_TTL", $ttl);
}
/**#@-*/
/**
* Class GMailer is the main class/library for interacting with Gmail (Google's
* free webmail service) with ease.
*
* <b>Acknowledgement</b><br/>It is not completely built from scratch. It is based on: "Gmail RSS feed in PHP"
* by thimal, "Gmail as an online backup system" by Ilia Alshanetsky, and "Gmail
* Agent API" by Johnvey Hwang and Eric Larson.
*
* Special thanks to Eric Larson and all other users, testers, and forum posters
* for their bug reports, comments and advices.
*
* @package GMailer
* @author Gan Ying Hung <ganyinghung|hide@address.com|users.sourceforge.net>
* @author Neerav Modi <neeravmodi|hide@address.com|users.sourceforge.net>
* @link http://gmail-lite.sourceforge.net Project homepage
* @link http://sourceforge.net/projects/gmail-lite Sourceforge project page
* @version 0.9.0-b8
*/
class GMailer {
/**#@+
* @access private
* @var string
*/
var $cookie_str;
var $cookie_array = array(); // Added by Neerav; 15 Mar 2007
var $login;
var $pwd;
/**
* Email domain
*
* Support for "Gmail for your domain".
* Domain name of email address to check.
*
* @access private
* @var string
* @author Neerav
* @since 8 Jun 2006
*/
var $domain;
var $GM_LNK_GMAIL = GM_LNK_GMAIL;
var $GM_LNK_GMAIL_A = GM_LNK_GMAIL;
var $GM_LNK_GMAIL_HTTP = GM_LNK_GMAIL_HTTP;
var $GM_LNK_LOGIN = GM_LNK_LOGIN;
var $GM_LNK_LOGIN_REFER = GM_LNK_LOGIN_REFER;
var $GM_LNK_INVITE_REFER = GM_LNK_INVITE_REFER;
var $GM_LNK_GMAIL_MOBILE = GM_LNK_GMAIL_MOBILE;
/**
* @author Neerav
* @since 13 Aug 2005
*/
var $gmail_data;
/**
* Raw packet
*/
var $raw;
/**
* Raw packet for contact list
*/
var $contact_raw;
var $timezone;
var $use_session;
var $proxy_host;
var $proxy_auth;
/**#@-*/
/**
* Reserved mailbox names
*/
var $gmail_reserved_names = array("inbox", "star", "starred", "chat", "chats", "draft", "drafts",
"sent", "sentmail", "sent-mail", "sent mail", "all", "allmail", "all-mail", "all mail",
"anywhere", "archive", "spam", "trash", "read", "unread");
/**
* @access public
* @var bool
*/
var $created;
/**
* Status of GMailer
*
* If something is wrong, check this class property to see what is
* going wrong.
*
* @author Neerav
* @since 8 July 2005
* @var mixed[]
* @access public
*/
var $return_status = array();
/**
* Constructor of GMailer
*
* During the creation of GMailer object, it will perform several tests to see
* if the cURL extension is available or not. However,
* note that the constructor will NOT return false or null even if these tests
* are failed. You will have to check the class property {@link GMailer::$created} to see if
* the object "created" is really, uh, created (i.e. working), and property
* {@link GMailer::$return_status} or method {@link GMailer::lastActionStatus()} to see what was going wrong.
*
* Example:
* <code>
* <?php
* $gmailer = new GMailer();
* if (!$gmailer->created) {
* echo "Error message: ".$gmailer->lastActionStatus("message");
* } else {
* // Do something with $gmailer
* }
* ? >
* </code>
*
* A typical usage of GMailer object would be like this:
* <code>
* <?php
* require_once("libgmailer.php");
*
* $gmailer = new GMailer();
* if ($gmailer->created) {
* $gmailer->setLoginInfo($gmail_acc, $gmail_pwd, $my_timezone);
* $gmailer->setProxy("proxy.company.com");
* if ($gmailer->connect()) {
* // GMailer connected to Gmail successfully.
* // Do something with it.
* } else {
* die("Fail to connect because: ".$gmailer->lastActionStatus());
* }
* } else {
* die("Failed to create GMailer because: ".$gmailer->lastActionStatus());
* }
* ? >
* </code>
*
* @see GMailer::$created, GMailer::$return_status, GMailer::lastActionStatus()
* @return GMailer
*/
function GMailer() {
// GMailer needs "curl" extension to work
$this->created = true;
if (!extension_loaded('curl')) {
// Added to gracefully handle multithreaded servers; by Neerav; 8 July 2005
if (isset($_ENV["NUMBER_OF_PROCESSORS"]) and ($_ENV["NUMBER_OF_PROCESSORS"] > 1)) {
$this->created = false;
$a = array(
"action" => "constructing GMailer object",
"status" => "failed",
"message" => "libgmailer: Using a multithread server. Ensure php_curl.dll has been enabled (uncommented) in your php.ini."
);
array_unshift($this->return_status, $a);
} else {
if (!dl('php_curl.dll') && !dl('curl.so')) {
$this->created = false;
$a = array(
"action" => "constructing GMailer object",
"status" => "failed",
"message" => "libgmailer: unable to load curl extension."
);
array_unshift($this->return_status, $a);
}
}
}
if (!function_exists("curl_setopt")) {
$this->created = false;
$a = array(
"action" => "constructing GMailer object",
"status" => "failed",
"message" => "libgmailer: No curl."
);
array_unshift($this->return_status, $a);
}
$this->login = 0;
$this->pwd = 0;
$this->domain = ""; // blank for @gmail.com and @googlemail.com
$this->proxy_host = "";
$this->proxy_auth = "";
$this->use_session = 2;
if ($this->created == true) {
$a = array(
"action" => "constructing GMailer object",
"status" => "success",
"message" => "libgmailer: Constructing completed."
);
array_unshift($this->return_status, $a);
}
}
/**
* Set Gmail's login information.
*
* @return void
* @param string $my_login Gmail's login name (without @gmail.com)
* @param string $my_pwd Password
* @param float $my_tz Timezone with respect to GMT, but in decimal. For example, -2.5 for -02:30GMT
*/
function setLoginInfo($my_login, $my_pwd, $my_tz) {
$this->login = $my_login;
$this->pwd = $my_pwd;
$this->timezone = strval($my_tz*-60);
// Added return_status; by Neerav; 16 July 2005
$a = array(
"action" => "set login info",
"status" => "success",
"message" => "libgmailer: LoginInfo set."
);
array_unshift($this->return_status, $a);
}
/**
* Set captch information.
*
* @return void
* @param string $text The captcha text
* @param string $token The captcha token
*/
function setCaptchaInfo($text, $token) {
$this->logincaptcha = $text;
$this->logintoken = $token;
$a = array(
"action" => "set Captcha info",
"status" => "success",
"message" => "libgmailer: Captcha set."
);
array_unshift($this->return_status, $a);
}
/**
* Set domain information if the account is on a hosted domain.
*
* @return void
* @param string $my_domain Hosted domain name (e.g., mydomain.org or sayni.net)
*/
function setDomain($my_domain) {
//return;
$my_domain = strtolower(trim($my_domain));
if ($my_domain === "" or $my_domain === 0 ) {
$a = array(
"action" => "set hosted domain info",
"status" => "sucess",
"message" => "libgmailer: Using the default gmail/googlemail domain."
);
array_unshift($this->return_status, $a);
return;
}
$success = true;
if (preg_match("/(^gmail\.com$)|(^googlemail\.com$)/i",$my_domain)) {
$a = array(
"action" => "set hosted domain info",
"status" => "failed",
"message" => "libgmailer: cannot use \"$my_domain\" as a hosted domain. The default gmail.com or googlemail.com will be used."
);
array_unshift($this->return_status, $a);
return;
}
$this->domain = $my_domain;
// GFYD urls changed to GAFYD; Neerav; 1 Sept 2006
// and finally, GM_LNK_GMAIL and GM_LNK_GMAIL_HTTP changed from hosted/ to a/; Neerav; 15 Mar 2007
//$this->GM_LNK_GMAIL = "https://mail.google.com/hosted/".$my_domain."/";
$this->GM_LNK_GMAIL = "https://mail.google.com/a/".$my_domain."/";
$this->GM_LNK_GMAIL_A = "https://mail.google.com/a/".$my_domain."/";
$this->GM_LNK_GMAIL_HTTP = "http://mail.google.com/a/".$my_domain."/";
$this->GM_LNK_LOGIN = "https://www.google.com/a/".$my_domain."/LoginAction";
$this->GM_LNK_LOGIN_REFER = "https://www.google.com/a/".$my_domain."/ServiceLogin?service=mail&passive=true&rm=false&continue=http%3A%2F%2Fmail.google.com%2Fhosted%2F".$my_domain."<mpl=yj_blanco<mplcache=2";
$this->GM_LNK_INVITE_REFER = "";
// Added by Neerav; 19 Jan 2007
$this->GM_LNK_GMAIL_MOBILE = "http://mail.google.com/a/".$my_domain."/x/";
$a = array(
"action" => "set hosted domain info",
"status" => "success",
"message" => "libgmailer: Domain set."
);
array_unshift($this->return_status, $a);
}
/**
* Setting proxy server.
*
* Example:
* <code>
* <?php
* // proxy server requiring login
* $gmailer->setProxy("proxy.company.com", "my_name", "my_pwd");
*
* // proxy server without login
* $gmailer->setProxy("proxy2.company.com", "", "");
* ? >
* </code>
*
* @return void
* @param string $host Proxy server's hostname
* @param string $username User name if login is required
* @param string $pwd Password if required
*/
function setProxy($host, $username, $pwd) {
if (strlen($host) > 0) { // fixed; Neerav; 14 Mar 2007
$this->proxy_host = $host;
if (strlen($username) > 0 || strlen($pwd) > 0) {
$this->proxy_auth = $username.":".$pwd;
}
$a = array(
"action" => "set proxy",
"status" => "success",
"message" => "libgmailer: Proxy set."
);
array_unshift($this->return_status, $a);
} else {
$a = array(
"action" => "set proxy",
"status" => "failed",
"message" => "libgmailer: no hostname supplied."
);
array_unshift($this->return_status, $a);
}
}
/**
* Setting session management method.
*
* You have to select a session management method so that GMailer would "remember"
* your identity. Method has to be one of the following values:
* 1. {@link GM_USE_COOKIE} | !{@link GM_USE_PHPSESSION} (if your server does not have PHP Session installed)
* 2. !{@link GM_USE_COOKIE} | {@link GM_USE_PHPSESSION} (if your server have PHP Session installed, and don't want to set browser's cookie)
* 3. {@link GM_USE_COOKIE} | {@link GM_USE_PHPSESSION} (if your server have PHP Session installed, and would like to use cookie to store session)
*
* @return void
* @param int $method
*/
function setSessionMethod($method) {
if ($method & GM_USE_PHPSESSION) {
if (!extension_loaded('session')) {
// Added to gracefully handle multithreaded servers; by Neerav; 8 July 2005
if (isset($_ENV["NUMBER_OF_PROCESSORS"]) and ($_ENV["NUMBER_OF_PROCESSORS"] > 1)) {
$this->setSessionMethod(GM_USE_COOKIE | !GM_USE_PHPSESSION); // forced to use custom cookie
$a = array(
"action" => "load PHP session extension",
"status" => "failed",
"message" => "Using a multithread server. Ensure php_session.dll has been enabled (uncommented) in your php.ini."
);
array_unshift($this->return_status, $a);
return;
} else {
// Changed extension loading; by Neerav; 18 Aug 2005
//if (!dl('php_session.dll') && !dl('session.so')) {
if (dl(((PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '') . 'session.' . PHP_SHLIB_SUFFIX)) {
$a = array(
"action" => "load PHP session extension",
"status" => "failed",
"message" => "unable to load PHP session extension."
);
array_unshift($this->return_status, $a);
$this->setSessionMethod(GM_USE_COOKIE | !GM_USE_PHPSESSION); // forced to use custom cookie
return;
}
}
}
$cookie_path = str_replace(DIRECTORY_SEPARATOR,"/",dirname($_SERVER['SCRIPT_NAME']))."/";
if ($cookie_path == "//") $cookie_path = "/";
@ini_set("session.cookie_path",$cookie_path);
if (!($method & GM_USE_COOKIE)) {
@ini_set("session.use_cookies", 0);
@ini_set("session.use_trans_sid", 1);
$a = array(
"action" => "setSessionMethod",
"status" => "success",
"message" => "not using cookie"
);
array_unshift($this->return_status, $a);
} else {
@ini_set("session.use_cookies", 1);
@ini_set("session.use_trans_sid", 0);
$a = array(
"action" => "setSessionMethod",
"status" => "success",
"message" => "using cookie"
);
array_unshift($this->return_status, $a);
}
@ini_set("arg_separator.output", '&');
session_start();
$a = array(
"action" => "setSessionMethod",
"status" => "success",
"message" => "using PHP session"
);
array_unshift($this->return_status, $a);
$this->use_session = true;
} else {
//@ini_set("session.use_only_cookies", 1);
@ini_set("session.use_cookies", 1);
@ini_set("session.use_trans_sid", 0);
$a = array(
"action" => "setSessionMethod",
"status" => "success",
"message" => "using only cookie"
);
array_unshift($this->return_status, $a);
$this->use_session = false;
}
}
/**
* @return binary image
* @desc
*/
// Finally got working!!; Neerav; 18 Oct 2006
function retrieveCaptcha($login, $logintoken) {
Debugger::say("retLogin: ".$login);
Debugger::say("retToken: ".$logintoken);
$login = str_replace("@gmail.com","",$login);
$c = curl_init();
curl_setopt($c, CURLOPT_URL, "https://www.google.com/accounts/Captcha?ctoken=".$logintoken."&email=".$login."%40gmail.com&cstyle=0");
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
// curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str);
//curl_setopt($c, CURLOPT_HEADER, 1);
curl_setopt($c, CURLOPT_REFERER, $this->GM_LNK_LOGIN);
//curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($c, CURLOPT_BINARYTRANSFER, 1);
$this->gmail_data = curl_exec($c);
curl_close($c);
return $this->gmail_data;
//return 1;
}
/**
* Connect to Gmail without setting any session/cookie
*
* @return bool Connect to Gmail successfully or not
*/
function connectNoCookie() {
$postdata = "";
if ($this->domain) {
$postdata .= "&at=null";
$postdata .= "&continue=".urlencode($this->GM_LNK_GMAIL);
$postdata .= "&service=mail";
$postdata .= "&userName=".urlencode($this->login);
$postdata .= "&password=".urlencode($this->pwd);
} else {
// "fixed"?!?; by Neerav; 1 Sept 2006
$postdata .= "<mpl=yj_blanco";
$postdata .= "<mplcache=2";
$postdata .= "&continue=".urlencode($this->GM_LNK_GMAIL);
$postdata .= "&service=mail";
$postdata .= "&rm=false";
$postdata .= "<mpl=yj_blanco";
$postdata .= "&hl=en";
$postdata .= "&Email=".urlencode($this->login);
$postdata .= "&Passwd=".urlencode($this->pwd);
$postdata .= "&rmShown=1";
$postdata .= "&null=Sign+in";
}
//Debugger::say(print_r($this->pwd,true));
//Debugger::say(print_r(urlencode($this->pwd),true));
//Debugger::say(print_r(urlencode(urldecode($this->pwd)),true));
//Debugger::say(print_r($postdata,true));
//exit;
// Check for valid hosted domains; Added by Neerav; 10 June 2006
if ($this->domain) {
if (preg_match("/(^yahoo\.)|(^hotmail\.)|(^(gala|sayni)\.net$)|(^(live|msn|rediffmail|gmail|googlemail|mail)\.com$)/i",$this->domain)
or
// invalid domain, doesn't even have a . in it!; Added by Neerav; 15 Jan 2007
(strpos($this->domain,".") === false)
) {
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => $this->domain." cannot be used as a 'Gmail for your domain' (hosted) domain.",
"login_error" => "invalid_domain"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
}
// Domain test
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_LOGIN_REFER,
"",
'get', "",
'nocookie', "",
false, // update cookie
true // follow // NOT needed
);
///Debugger::say(__FILE__.": ".__LINE__.": "."check for valid GFYD: ".print_r($this->gmail_data,true));
//exit;
if ( strpos($this->gmail_data,'<div class="x"> Sign in to your account at <h2>') > 0
or
strpos($this->gmail_data,'<input type="hidden" name="continue" value="http://mail.google.com/hosted/'.$this->domain.'">') > 0
) {
// domain exists
///Debugger::say("hosted domain found");
} elseif (
// updated domain not found error after Gmail for your Domain now known
// as Google apps for your domain; Neerav; 14 Sept 2006
strpos($this->gmail_data,"Google Apps for Your Domain - Server error") > 0
or
strpos($this->gmail_data,"<p>Sorry, you've reached a login page for a domain that isn't using Google Apps for Your Domain. Please check the web address and try again.</p>") > 0
or
strpos($this->gmail_data,"<p>Sorry, you've reached a login page for a domain that isn't using Google Apps. Please check the web address and try again.</p>") > 0
or
strpos($this->gmail_data,"<p>Domain does not exist</p>") > 0
or
strpos($this->gmail_data,"Gmail for your domain - Server error") > 0
) {
// domain does not exist
///Debugger::say("hosted domain NOT found");
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Gmail for your domain - Server error -- Domain does not exist",
"login_error" => "domain_nonexist"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
}
}
// Added by Neerav; 8 July 2005
// Finally implemented 18 Oct 2006
// login challenge
if (isset($this->logintoken) and $this->logintoken !== "") $postdata .= "&logintoken=".$this->logintoken;
if (isset($this->logincaptcha) and $this->logincaptcha !== "") $postdata .= "&logincaptcha=".$this->logincaptcha;
/* Debugger::say(print_r($postdata,true)); */
/* exit; */
// The GMAIL_LOGIN cookie is now required since 31 Aug 2006; by Neerav; 1 Sept 2006
$time = time();
// we fake that the user loaded the browser 4-20 seconds ago
$time_past = $time - rand(4,20);
// create the cookie
$cookie = "GMAIL_LOGIN=T$time_past/$time_past/$time";
// added in case it's needed in the future; Neerav; 1 Sept 2006
//if ($this->domain) {
// // Gmail's "user ping"
// // pre first phase, sending word that this user is about to sign in.
// $this->gmail_data = GMailer::execute_curl(
// $this->GM_LNK_GMAIL."?gxlu=".urlencode($this->login)."&zx=".(time()-rand(2,6)).rand(100,999),
// (($this->domain) ? $this->GM_LNK_LOGIN : $this->GM_LNK_LOGIN_REFER),
// 'get',
// "",
// 'cookie', "GMAIL_LOGIN=T$time_past/$time_past/$time"
// );
// Debugger::say("pre first phase: ".print_r($this->gmail_data,true));
//}
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_LOGIN,
(($this->domain) ? $this->GM_LNK_LOGIN : $this->GM_LNK_LOGIN_REFER),
'post',
$postdata,
// changed to use the required time cookie; by Neerav; 1 Sept 2006
//'nocookie', ""
(($this->domain) ? 'nocookie': 'cookie'), (($this->domain) ? '' : "$cookie")
);
///Debugger::say("first phase: ".print_r($this->gmail_data,true));
//exit;
$a = array(
"action" => "connecting to Gmail (without cookie)",
"status" => (($this->gmail_data != "") ? "success" : "failed"),
"message" => (($this->gmail_data != "") ? "connected to Gmail (without cookie)" : "no response"),
"login_error" => (($this->gmail_data != "") ? "" : "no response")
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
if ($this->gmail_data == "") return false;
/** from here we have to perform "cookie-handshaking"... **/
$cookies = GMailer::get_cookies($this->gmail_data);
///Debugger::say("first phase cookies: ".print_r($cookies,true));
//exit;
$this->logintoken = "";
$this->logincaptcha = "";
// hosted domains signin changed by Gmail; Neerav; 18 May 2007
if ($this->domain and strpos($this->gmail_data,$this->domain."/?auth=") !== false) {
// no error, already have the auth code and Location
$cookies = "";
$second = $this->gmail_data; // the skip hosted domain phase
///Debugger::say("hosted domain auth recieved: ".print_r($data,true));
// updated if condition for hosted domains; by Neerav; 8 June 2006
} elseif ((
strpos($this->gmail_data, "errormsg_0_Passwd") > 0
or
strpos($this->gmail_data, "errormsg_0_password") > 0
) and
strpos($this->gmail_data, "Username and password do not match") > 0
){
$this->cookie_str = "";
$this->cookie_ik_str = "";
// Added appropriate error message; by Neerav; 8 July 2005
// Added error message for suggested username; by Neerav; 28 July 2006
if (preg_match("/Did you mean(.*?)\?\)/i",$this->gmail_data,$userpass_match)) {
$suggest = trim($userpass_match[1]);
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Username and password do not match. (Did you mean ".$suggest." ?)",
"login_error" => "userpass_suggest",
"login_suggest" => $suggest
);
} else {
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Username and password do not match. (You provided ".$this->login.")",
"login_error" => "userpass"
);
}
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
// Blank username or password; Added by Neerav; 8 June 2006
} elseif (
(
strpos($this->gmail_data, "errormsg_0_password") > 0
or
strpos($this->gmail_data, "errormsg_0_userName") > 0
or
strpos($this->gmail_data, "errormsg_0_username") > 0
) and
strpos($this->gmail_data, "Required field must not be blank") > 0
) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Required field must not be blank",
"login_error" => "blank"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
// Added to support login challenge; by Neerav; 8 July 2005
} elseif (strpos($this->gmail_data, "errormsg_0_logincaptcha") > 0) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
//id="logintoken" value="cpxxx-yyy:zzz" name="logintoken">
ereg("id=\"logintoken\" value=\"([^\"]*)\" name=\"logintoken\"", $this->gmail_data, $matches);
///Debugger::say("Connect FAILED: login challenge: ".$this->gmail_data);
///Debugger::say("ErrorLogin: ".$this->login);
///Debugger::say("ErrorToken: ".$matches[1]);
///Debugger::say("logintoken: ".print_r($matches,true));
// Added appropriate error message; by Neerav; 8 July 2005
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "login challenge",
"login_token" => $matches[1],
"login_error" => "challenge"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
// Check if the Gmail URL has changed; Added by Neerav; 14 Sept 2005
} elseif (strpos($this->gmail_data, "Invalid request.")) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Gmail: Invalid request. (libgmailer: Gmail seems to have changed the URL again.)",
"login_error" => "URL"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
// Other custom Gmail error; Added by Neerav; 18 Jan 2007
} elseif (preg_match("@<div[^>]*errormsg_0_errMsg[^>]*>(.*)</div>@Uis",$this->gmail_data,$matches)) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => $matches[1],
"login_error" => "custom"
);
array_unshift($this->return_status, $a);
return false;
// Check for first time signin for hosted domain users; Addd by Neerav; 25 Jan 2007
} elseif (strpos($this->gmail_data, 'action="SetupAccountAction"')) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "User needs to signin through a PC to setup the account.",
"login_error" => "newly_created"
);
array_unshift($this->return_status, $a);
return false;
// Check for hosted domains that need to be set up; Addd by Neerav; 26 Jan 2007
} elseif ($this->domain and strpos($this->gmail_data, 'Location: /a/register?n=')) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "This Google Apps for Your Domain needs to be first set up.",
"login_error" => "domain_setup"
);
array_unshift($this->return_status, $a);
return false;
// Check for a cookie as a way to check the Gmail URL; Added by Neerav; 14 Sept 2005
// For hosted domains, the cookie may be blank in some cases; changed by Neerav; 15 Mar 2007
} elseif ((!$this->domain and $cookies == "") or ($this->domain and strpos($this->gmail_data,"AuthEventSource=Internal&auth=") === false and $cookies == "")) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "libgmailer: Phase one cookie not obtained. Gmail may be down.",
"login_error" => "cookie"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
}
$a = array(
"action" => "phase one cookie",
"status" => "success",
"message" => "Received: ".$cookies
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
$host_redir_url = "";
// Phase for hosted domains
if (strpos($cookies, "HID=") !== false or ($this->domain and strpos($this->gmail_data,"AuthEventSource=Internal&auth=") !== false)) {
if (preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$this->gmail_data,$matches)) {
///Debugger::say(__FILE__.": ".__LINE__.": "."hosted phase location match: ".print_r($matches,true));
if (strpos($matches[1],"http") !== 0) {
// be prepared for relative url
$host_redir_url = "https://www.google.com".$matches[1];
//$redirect_scheme = "rel";
} else {
// currently fully qualified url
$host_redir_url = $matches[1];
//$redirect_scheme = "fullqual";
}
} else {
$preg = preg_match("/HID=([^ ;]*)/",$cookies,$hosted_auth);
$host_redir_url = $this->GM_LNK_GMAIL.'?auth='.$hosted_auth[1];
///Debugger::say(__FILE__.": ".__LINE__.": "."hosted phase auth: ".print_r($hosted_auth,true));
}
$a = array(
"action" => "phase 'hosted domain'",
"status" => "status",
"message" => "Redirect: to ".$host_redir_url
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
//exit;
// execute hosted domain phase of signin
if ($cookies != "") {
$this->gmail_data = GMailer::execute_curl(
$host_redir_url,
"", // no referrer
'get', "",
"cookie", $cookies,
true, // update cookies
false // do not follow location
);
} else {
$this->gmail_data = GMailer::execute_curl(
$host_redir_url,
"", // no referrer
'get', "",
"nocookie", $cookies,
false, // update cookies (no cookies to update!)
false // do not follow location
);
}
// hosted phase cookies
// no cookies to be had
//$data = GMailer::get_cookies($this->gmail_data);
///Debugger::say(__FILE__.": ".__LINE__.": "."hosted phase: ".print_r($this->gmail_data,true));
//Debugger::say(__FILE__.": ".__LINE__.": "."hosted phase cookies: ".print_r($data,true));
//exit;
// status
$a = array(
"action" => "phase 'hosted domain'",
"status" => "status",
"message" => "done"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
}
if ($this->domain) {
$second = $this->gmail_data;
$forward = $host_redir_url;
} else {
// Forward url is now absolute instead of relative; Fixed by Gan; 27 July 2005
$a = strpos($this->gmail_data, "Location: ");
$b = strpos($this->gmail_data, "\n", $a);
$forward = substr($this->gmail_data, $a+10, $b-($a+10));
// accomodate absolute and relative urls; Fixed by Neerav; 28 Sept 2006
/* preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$this->gmail_data,$matches); */
///Debugger::say("determining second phase location: ".print_r($matches,true));
/* if (strpos($matches[1],"http") !== 0) { */
/* $forward = "https://www.google.com".$matches[1]; */
/* } else { */
/* $forward = $matches[1]; */
/* } */
$a = array(
"action" => "redirecting",
"status" => "success",
"message" => "Redirecting to second phase: ".$forward
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
// Added extra required cookie; by Neerav; 4 Apr 2006
$second = GMailer::execute_curl(
$forward,
$this->GM_LNK_LOGIN_REFER,
'get', "",
"cookie", "GoogleAccountsLocale_session=en; ".$cookies
);
}
// workaround for open_basedir and curl FOLLOWLOCATION php >= 4.4.4; Neerav; 14 Sept 2006
/* if ( version_compare(PHP_VERSION, "4.4.4", ">=") */
/* and version_compare(PHP_VERSION, "5.0.0", "<") */
/* and ini_get('open_basedir') != "" */
/* ) { */
$redirect_scheme = "";
if ($this->domain) {
if (preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$second,$matches)) {
if (strpos($matches[1],"http") !== 0) {
// currently relative url
// changed from www.google.com to mail.google.com; Neerav; 15 Mar 2007
$redir_url = "https://mail.google.com".$matches[1];
$redirect_scheme = "rel";
} else {
// be prepared for fully qualified url
$redir_url = $matches[1];
$redirect_scheme = "fullqual";
}
} else {
// no more redirection
$redir_url = "";
$redirect_scheme = "fullqual";
}
///Debugger::say("open_basedir, domain, location: ".print_r($matches,true));
} else {
if (preg_match("/Location:\s*(http(s)?:\/\/(.*?))(\r)?\n/s",$second,$matches)) {
$redir_url = $matches[1];
$redirect_scheme = "loc";
// New redirection scheme for some accounts; Neerav; 22 Sept 2006
} elseif (preg_match("/url=['\"](http(s)?:\/\/([^'\"]*?))['\"]/s",$second,$matches)) {
// skip directly to phase three
$redir_url = "none. Meta redirect. Skipping to phase three.";
$redirect_scheme = "meta";
} elseif ( strpos($second, "You cannot log into Gmail using your Google Account username and password.") !== false
/* or */
/* strpos($second, "You cannot log into Gmail using your Google Account username and password.") !== false */
) {
// using a Google Accounts login
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Sorry, this is not a valid Gmail login. You cannot log into Gmail using your Google Account username and password.",
"login_error" => "google_account"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
} elseif (strpos($second, "500 Internal Server Error") !== false) {
// internal server error
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Gmail Internal Server Error",
"login_error" => "500"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return false;
} else {
$redir_url = "?!?!?";
$a = array(
"action" => "sign in",
"status" => "failed",
"message" => "Gmail: Invalid request. (libgmailer: Gmail seems to have changed the URL again.)",
"login_error" => "URL"
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
Debugger::say("second (open_basedir) phase location STILL not matched ".__FILE__.": ".__LINE__.": ".print_r($this,true));
return false;
}
}
$a = array(
"action" => "second (open_basedir) phase",
"status" => "status",
"message" => "Using open_basedir workaround, manual redirection to:\n".$redir_url
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
if ($this->domain) {
// we need these cookies
$cookies = GMailer::get_cookies($second);
// Sometimes, a hosted account doesn't need any redirection. Why?
if ($redir_url != "") {
///Debugger::say(__FILE__.": ".__LINE__.": "."host domain cookies: "."GoogleAccountsLocale_session=en; ".$cookies);
///Debugger::say(__FILE__.": ".__LINE__.": "."redirect url: ".$redir_url);
//exit;
$second = GMailer::execute_curl(
$redir_url,
$forward,
'get', "",
"cookie", "GoogleAccountsLocale_session=en; ".$cookies
);
///Debugger::say(__FILE__.": ".__LINE__.": second (open_basedir) phase: ".print_r($second,true));
// signin change; Neerav; 18 May 2007
if (strpos($second, "indexOf('nocheckbrowser')") !== false) {
$data = GMailer::get_cookies($second);
}
if (preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$second,$matches)) {
$data = GMailer::get_cookies($second);
///Debugger::say(__FILE__.": ".__LINE__.": "."second (open_basedir post 2) phase cookies: ".print_r($data,true));
// change to accept absolute AND relative urls; Neerav; 22 Sept 2006
if (strpos($matches[1],"http") !== 0) {
// prepare for relative url
// changed from www.google.com to mail.google.com; Neerav; 15 Mar 2007
$redir_url2 = "https://mail.google.com".$matches[1];
$redirect_scheme = "rel";
} else {
// currently fully qualified url
$redir_url2 = $matches[1];
$redirect_scheme = "fullqual";
}
// ANOTHER redirection :-(
$a = array(
"action" => "second (open_basedir 2) phase",
"status" => "status",
"message" => "Using open_basedir workaround, manual redirection to:\n".$redir_url2
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
$second = GMailer::execute_curl(
$redir_url2,
$redir_url,
'get', "",
"cookie", "GoogleAccountsLocale_session=en; ".$data/* ."; dhc=test;" */
);
if (strpos($data,"GXAS_SEC") !== false) {
// if the gxas_sec cookie already set, then just cat the cookies; added by Neerav; 15 mar 2007
// Google's new way since 14 Mar 2007
$data .= "; ".GMailer::get_cookies($second);
} else {
$data = GMailer::get_cookies($second);
}
///Debugger::say(__FILE__.": ".__LINE__.": "."second (open_basedir 2) phase: ".print_r($second,true));
///Debugger::say(__FILE__.": ".__LINE__.": "."second (open_basedir 2) phase cookies: ".print_r($data,true));
}
}
} else {
$data = GMailer::get_cookies($second);
/* print($redirect_scheme); */
/* Debugger::say("old cookie: ".$cookies); */
/* Debugger::say("old cookie cleaned: "."GoogleAccountsLocale_session=en; ".preg_replace("/LSID=.*$/","",$cookies)); */
/* Debugger::say("_data (new cookie): ".$data); */
/* Debugger::say("redirect url: ".$redir_url); */
/* exit; */
if ($redirect_scheme == "meta") {
// New redirection scheme for some accounts; Neerav; 22 Sept 2006
// skip directly to phase three
} else {
// "regular" redirection scheme prior to 22 Sept 2006
$second = GMailer::execute_curl(
$redir_url,
$forward,
'get', "",
"cookie", "GoogleAccountsLocale_session=en; ".preg_replace("/LSID=.*$/","",$cookies).$data
);
$data = GMailer::get_cookies($second);
//Debugger::say("second (open_basedir) phase: ".print_r($second,true));
//Debugger::say("second (open_basedir) phase cookies: ".print_r($data,true));
}
}
$a = array(
"action" => "phase two cookie",
"status" => "success",
"message" => "Obtained: ".((isset($data)) ? $data : '' )
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
/* $this->cookie_str = $cookies.";".$d; // the cookie string obtained from gmail */
// Third phase required for some accounts. Added by Neerav; April 2006
if (strpos($second, "SetSID") !== false) {
$forward = preg_match("/<meta content=\"0;\s*url='?([^\"\']*)'?\"/",$second,$matches);
$a = array(
"action" => "phase three required",
"status" => "status",
"message" => "Redirect: ".str_replace("&","&",$matches[1])
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
///Debugger::say("third phase to forward (all matches): ".print_r($matches,true));
// save url for post 3rd phase redirect
$third_url = str_replace("&","&",$matches[1]);
// execute third phase of signin
$third = GMailer::execute_curl(
$third_url,
"", // no referrer
'get', "",
"nocookie", "");
// third phase cookies
$data = GMailer::get_cookies($third);
///Debugger::say("third phase: ".print_r($third,true));
///Debugger::say("third phase cookies: ".print_r($data,true));
// status
$a = array(
"action" => "phase three cookie",
"status" => "success",
"message" => "Obtained: ".$data
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
// Added manual redirection; Neerav; 23 Sept 2006
if (preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$third,$matches)) {
if (strpos($matches[1],"http") !== 0) {
// prepare for relative url
$redir_url = "https://www.google.com".$matches[1];
} else {
// currently fully qualified url
$redir_url = $matches[1];
}
///Debugger::say("phase three manual redirect url: ".$redir_url);
///Debugger::say("phase three manual redirect refer: ".$third_url);
///Debugger::say("phase three manual redirect cookie: "."GoogleAccountsLocale_session=en; ".$data);
$third_manual_red = GMailer::execute_curl(
$redir_url,
$third_url,
'get', "",
"cookie", "GoogleAccountsLocale_session=en; ".$data
);
$data = GMailer::get_cookies($third_manual_red);
}
}
$data = ((isset($data) and $data) ? $data : str_replace("dhc=test","",$cookies))."; TZ=".$this->timezone;
///Debugger::say(__FILE__.": ".__LINE__.": "."cookies (pre-clean): ".print_r($data,true));
// remove duplicate cookies
$data = preg_replace("/GX=.*?;\s?GX=/","GX=",$data);
// remove unnecessary LSID, if it still exists.
$data = trim(preg_replace("/LSID=mail[^;]*?;/","",$data));
///Debugger::say(__FILE__.": ".__LINE__.": "."final cookies (corrected/cleaned): ".print_r($data,true));
$this->cookie_str = $data;
$a = array(
"action" => "final gmail cookie",
"status" => "status",
"message" => "Cookie: ".$data
);
array_unshift($this->return_status, $a);
///Debugger::say(__FILE__.": ".__LINE__.": ".print_r($a,true));
return true;
}
/**
* Connect to GMail with default session management settings.
*
* @return bool Connect to Gmail successfully or not
*/
function connect() {
if ($this->use_session === 2)
$this->setSessionMethod(GM_USE_COOKIE | GM_USE_PHPSESSION); // by default
// already logged in
if ($this->login == 0 && $this->pwd == 0) {
if (!$this->getSessionFromBrowser()) {
return $this->connectNoCookie() && $this->saveSessionToBrowser();
} else {
$a = array(
"action" => "connect",
"status" => "success",
"message" => "Connect completed by getting cookie/session from browser/server."
);
array_unshift($this->return_status, $a);
return true;
}
// log in
} else {
// Changed to support login challenge; by Neerav; 8 July 2005
//return $this->connectNoCookie() && $this->saveSessionToBrowser();
if ($this->connectNoCookie()) {
return $this->saveSessionToBrowser();
} else {
return false;
}
}
}
/**
* See if it is connected to GMail.
*
* @return bool
*/
function isConnected() {
return (strlen($this->cookie_str) > 0);
}
/**
* Last action's action, status, message, and other info
*
* @param string $request What information you would like to request. Default is "message".
* @return string
*/
function lastActionStatus($request = "message") {
if ($request == "message") {
return preg_replace("/(\s| )*<(a|span)[^>]*[^<]*<\/(a|span)>/","",$this->return_status[0]["$request"]);
} else {
return $this->return_status[0]["$request"];
}
}
/**
* Append a random string to url to fool proxy
*
* @param string $type Set to "nodash" if you do not want a dash ("-") in random string. Otherwise just leave it blank.
* @access private
* @return string Complete URL
* @author Neerav
* @since June 2005
*/
function proxy_defeat($type = "") {
$length = 12;
$seeds = 'abcdefghijklmnopqrstuvwxyz0123456789';
$string = '';
$seeds_count = strlen($seeds);
// Generate
// Changed to also use without dash; by Neerav; 11 Aug 2005
if ($type == "nodash") {
for ($i = 0; $length > $i; $i++) {
$string .= $seeds{mt_rand(0, $seeds_count - 1)};
}
} else {
for ($i = 0; $length > $i; $i++) {
$string .= $seeds{mt_rand(0, $seeds_count - 1)};
if ($i == 5) $string .= "-"; // Added by Neerav; 28 June 2005
}
}
return "&zx=".$string;
}
/**
* Fetch contents by URL query.
*
* This is a "low-level" method. Please use {@link GMailer::fetchBox()} for fetching standard contents.
*
* @param string $query URL query string
* @return bool Success or not
*/
function fetch($query) {
if ($this->isConnected() == true) {
Debugger::say("Start fetching query: ".$query);
$query .= $this->proxy_defeat(); // to fool proxy
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
$this->GM_LNK_GMAIL."?ik=&search=inbox&view=tl&start=0&init=1".$this->proxy_defeat(),
'get'
);
GMailer::parse_gmail_response($this->gmail_data);
Debugger::say("Fetch completed.");
return 1;
} else { // not logged in yet
Debugger::say("Fetch FAILED: not connected.");
return 0;
}
}
/**
* Fetch contents from Gmail by type.
*
* Content can be one of the following categories:
* 1. {@link GM_STANDARD}: For standard mail-boxes like Inbox, Sent Mail, All, etc. In such case, $box should be the name of the mail-box: "inbox", "all", "sent", "draft", "spam", or "trash". $paramter would be used for paged results.
* 2. {@link GM_LABEL}: For user-defined label. In such case, $box should be the name of the label.
* 3. {@link GM_CONVERSATION}: For conversation. In such case, $box should be the conversation ID and $parameter should be the mailbox/label in which the message is found (if supplied 0, it will default to "inbox").
* 4. {@link GM_QUERY}: For search query. In such case, $box should be the query string.
* 5. {@link GM_PREFERENCE}: For Gmail preference. In such case, $box = "".
* 6. {@link GM_CONTACT}: For contact list. In such case, $box can be either "all", "search", "detail", "group", or "group detail". When $box = "detail", $parameter is the Contact ID. When $box = "search", $parameter is the search query string.
*
* @return bool Success or not
* @param constant $type Content category
* @param mixed $box Content type
* @param int $parameter Extra parameter. See above.
* @see GM_STANDARD, GM_LABEL, GM_CONVERSATION, GM_QUERY, GM_PREFERENCE, GM_CONTACT
*/
function fetchBox($type, $box, $parameter) {
if ($this->isConnected() == true) {
switch ($type) {
case GM_STANDARD:
$q = "search=".strtolower($box)."&view=tl&start=".$parameter;
break;
case GM_LABEL:
$q = "search=cat&cat=".$box."&view=tl&start=".$parameter;
break;
case GM_CONVERSATION:
if ($parameter === 0 or $parameter == "") $parameter = "inbox";
if (in_array(strtolower($parameter),$this->gmail_reserved_names)) {
$q = "search=".urlencode($parameter)."&ser=1&view=cv";
} else {
$q = "search=cat&cat=".urlencode($parameter)."&ser=1&view=cv";
}
if (is_array($box)) {
$q .= "&th=".$box[0];
for ($i = 1; $i < count($box); $i++)
$q .= "&msgs=".$box[$i];
} else {
$q .= "&th=".$box;
}
break;
case GM_QUERY:
$q = "search=query&q=".urlencode($box)."&view=tl&start=".$parameter;
break;
case GM_PREFERENCE:
$q = "view=pr&pnl=g";
break;
case GM_CONTACT:
if (strtolower($box) == "all")
$q = "view=cl&search=contacts&pnl=a";
elseif (strtolower($box) == "search") // Added by Neerav; 15 June 2005
$q = "view=cl&search=contacts&pnl=s&q=".rawurlencode($parameter);
elseif (strtolower($box) == "detail") // Added by Neerav; 1 July 2005
$q = "search=contacts&ct_id=".$parameter."&cvm=2&view=ct".$this->proxy_defeat();
elseif (strtolower($box) == "group_detail") // Added by Neerav; 6 Jan 2006
$q = "search=contacts&ct_id=".$parameter."&cvm=1&view=ctl".$this->proxy_defeat();
elseif (strtolower($box) == "group")
$q = "view=cl&search=contacts&pnl=l";
else // frequently mailed
$q = "view=cl&search=contacts&pnl=p";
break;
default:
$q = "search=inbox&view=tl&start=0&init=1";
break;
}
$this->fetch($q);
return true;
} else {
return false;
}
}
/**
* Get a message source from a given msgid
* @return string
* @param string $msgid
* @desc Get the e-mail source or a given message id
*/
function getMessageSource ($msgid) {
if ($this->isConnected()) {
$query = "view=om&th=$msgid";
Debugger::say("Getting message $msgid source...");
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_URL, GM_LNK_GMAIL."?".$query);
curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
curl_setopt($c, CURLOPT_REFERER, GM_LNK_REFER);
$message = curl_exec($c);
curl_close($c);
return $message;
} else {
Debugger::say("Failed to get message $msgid source");
return 0;
}
}
/**
* Save all attaching files of conversations to a path.
*
* Random number will be appended to the new filename if the file already exists.
*
* @return string[] Name of the files saved. False if failed.
* @param string[] $convs Conversations.
* @param string $path Local path.
*/
function getAttachmentsOf($convs, $path) {
if ($this->isConnected() == true) {
if (!is_array($convs)) {
$convs = array($convs); // array wrapper
}
$final = array();
foreach ($convs as $v) {
if (count($v["attachment"]) > 0) {
foreach ($v["attachment"] as $vv) {
$f = $path."/".$vv["filename"];
while (file_exists($f)) {
$f = $path."/".$vv["filename"].".".round(rand(0,1999));
}
if ($this->getAttachment($vv["id"],$v["id"],$f,false)) {
array_push($final, $f);
}
}
}
}
return $final;
} else {
return false;
}
}
/**
* Save attachment with attachment ID $attach_id and message ID $msg_id to file with name $filename.
*
* @return bool Success or not.
* @param string $attach_id Attachment ID.
* @param string $msg_id Message ID.
* @param string $filename File name.
* @param bool $action {zip = Save all attachments into a zip file; embed = html-embedded image; thumb = retrieve picture thumbnail; smthumb = (notworking)retrieve small (mobile) picture thumbnail; convert = view html converted form of doc/pdf/xls/rtf/ppt}.
* @param bool $thumbnail download the attachment's thumbnail.
*/
function getAttachment($attach_id, $msg_id, $filename, $action = "") {
if ($this->isConnected() == true) {
Debugger::say("Start getting attachment...");
if ($action == "thumb") {
// view thumbnail; Added by Neerav; 22 Aug 2006
// /mail/?realattid=0.1&attid=0.1&disp=thd&view=att&th=10f9a2dfb4xxxxx (captured 19 Dec 2006)
$query = $this->GM_LNK_GMAIL."?view=att&disp=thd&attid=".urlencode($attach_id)."&th=".urlencode($msg_id);
/* } elseif ($action == "smthumb") { */
/* // view small (mobile) thumbnail; Added by Neerav; 6 Oct 2006 */
/* $query = $this->GM_LNK_GMAIL_HTTP."x/".str_replace("&zx=","",$this->proxy_defeat("nodash"))."-/?"/* ."realattid=file0&" * /."attid=".urlencode($attach_id)."&disp=thd&view=att&th=".urlencode($msg_id); */
/* //$refer = $this->GM_LNK_GMAIL_HTTP."x/".str_replace("&zx=","",$this->proxy_defeat("nodash"))."-/?v=att&mi=0&th=".urlencode($msg_id); */
/* //Debugger::say($query); */
/* Debugger::say("Thumbnail cookie: ".$this->cookie_str); */
/* $fp = fopen($filename, "wb"); */
/* if ($fp) { */
/* $c = curl_init(); */
/* curl_setopt($c, CURLOPT_FILE, $fp); */
/* curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str); */
/* curl_setopt($c, CURLOPT_URL, $query); */
/* //curl_setopt($c, CURLOPT_REFERER, $refer); */
/* $this->CURL_PROXY(&$c); */
/* //curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); */
/* //curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE); */
/* curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT); */
/* curl_exec($c); */
/* curl_close($c); */
/* fclose($fp); */
/* Debugger::say("Completed getting attachment."); */
/* return true; */
/* } else { */
/* Debugger::say("FAILED to get attachment: cannot fopen the file."); */
/* return false; */
/* } */
} elseif ($action == "embed" or $action == "embed_head") {
// html-embedded images
/* /mail/?attid=0.1&disp=emb&view=att&th=xxxxxxx */
$query = $this->GM_LNK_GMAIL_HTTP."?attid=".urlencode($attach_id)."&disp=emb&view=att&th=".urlencode($msg_id);
} elseif ($action == "zip") {
// all attachments zipped
$query = $this->GM_LNK_GMAIL."?view=att&disp=zip&th=".urlencode($msg_id);
} elseif ($action == "convert") {
// pdf, rtf, xls, doc, ppt converted into html
// ** using Gmail Mobile to retrieve this **
$query = "x/".str_replace("&zx=","",$this->proxy_defeat("nodash"))."-/?disp=vah&attid=".urlencode($attach_id)."&th=".urlencode($msg_id)."&v=att";
$this->gmail_data = GMailer::execute_curl(
/* $this->GM_LNK_GMAIL_HTTP.$query, */
$this->GM_LNK_GMAIL.$query, // Google changed to using https; Neerav; 15 Mar 2007
/* $this->GM_LNK_GMAIL_HTTP."x/".str_replace("&zx=","",$this->proxy_defeat("nodash"))."-/?mi=0&th=".urlencode($msg_id)."&v=att", */
"",//$this->GM_LNK_GMAIL_HTTP."x/".$this->proxy_defeat("nodash")."-/?v=cmf",
'get',"",
"noheader"
);
//Debugger::say(print_r($this->gmail_data,true));
if (strpos($this->gmail_data,'gmail_error=') !== false) {
preg_match("/gmail_error=(\d+);/",$this->gmail_data,$error_num);
$error = (isset($error_num[1])) ? $error_num[1] : "" ;
if ( $error != 25 //
and $error != 15 // attachment cannot be viewed, e.g. trying to convert a jpeg into html!
and $error != 58 // server error (what's the real reason?)
and $error != 7 // attachment doesn't exist (gmail gives "server error")
and $error != 70 // Gmail unavailable (in eastern european?)
) {
Debugger::say(print_r($this->gmail_data,true),"error_log.glib.as_html.php");
}
// tries to regex the error message from Gmail's response
if ($error == 58 or $error == 7 or $error == 70) {
// error message is the only text in <p> tags.
preg_match("@<p>(.*?)</p>@is",$this->gmail_data,$match_error);
} else {
// Many <p> tags found, the error message is in <font>
preg_match('@<p><font size="-1">(.*?)</font></p>@is',$this->gmail_data,$match_error);
}
if (isset($match_error[1]) and trim($match_error[1]) != "") {
$message = trim($match_error[1]);
} else {
Debugger::say("The error message did not match the regex: \n".print_r($this->gmail_data,true),"error_log.glib.as_html.php");
$message = "Gmail reported an unknown error.<br/><br/><b>DO NOT REPEAT OR RELOAD.</b>";
}
$a = array(
"action" => "view as html",
"status" => "failed",
"message" => "<p>$message</p>",
"error" => $error
);
array_unshift($this->return_status, $a);
return false;
}
preg_match("/<body>(.*)<\/body>/",$this->gmail_data,$match);
//Debugger::say(print_r($match[1],true));
$a = array(
"action" => "view as html",
"status" => "success",
"message" => "attachment converted to html and received",
"error" => 0,
"as_html" => $match[1]
);
array_unshift($this->return_status, $a);
return true;
} else {
// download attachment
$query = $this->GM_LNK_GMAIL."?view=att&disp=attd&attid=".urlencode($attach_id)."&th=".urlencode($msg_id);
}
// view all images
/* $query = $this->GM_LNK_GMAIL."?view=att&disp=imgs&th=".urlencode($msg_id); */
// view image inline
/* $query = $this->GM_LNK_GMAIL."?view=att&disp=inline&attid=".urlencode($attach_id)."&th=".urlencode($msg_id); */
$this->attach_info = array("size" => "", "filename" => "", "type" => "");
$this->send_headers = ($action == "embed") ? true: false;
$fp = fopen($filename, "wb");
if ($fp) {
$c = curl_init();
if ($action == "embed_head") {
// AVOID USING THIS! GMAIL DOESN'T REALLY SUPPORT IT.
// THE ONLY USEFUL THING FROM IT WILL BE THE ATTACHMENT NAME
// THE CONTENT LENGTH WILL ALWAYS BE 0 AND THE MIME TYPE
// WILL ALWAYS BE TEXT/HTML (SINCE IT'S AN ERROR MESSAGE)
// retrieve only the header
curl_setopt($c, CURLOPT_CUSTOMREQUEST, "HEAD");
//Debugger::say("url: ".$query);
//curl_setopt($c, CURLOPT_URL, "http://glite.sayni.net/litelogo.gif");
}
curl_setopt($c, CURLOPT_FILE, $fp);
curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str);
curl_setopt($c, CURLOPT_URL, $query);
//curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
curl_setopt($c, CURLOPT_REFERER, $this->GM_LNK_GMAIL."?ik=&search=inbox&view=tl&start=0&init=1".$this->proxy_defeat());
// Get/supply details about the file; Neerav; 25 Oct 2006
/* if ($action == "embed" or $action == "embed_head") { */
/* //curl_setopt($c, CURLOPT_WRITEHEADER, $this->attach_info); */
curl_setopt($c, CURLOPT_HEADERFUNCTION, array(&$this,'_setHeader'));
/* } */
/* $fd = fopen("debug_curl.txt", "a+"); */
/* curl_setopt($c, CURLOPT_VERBOSE, 1); */
/* curl_setopt($c, CURLOPT_STDERR, $fd); */
curl_exec($c);
curl_close($c);
fclose($fp);
/* fclose($fd); */
//Debugger::say(print_r($this,true));
/* Debugger::say(print_r($this->headers,true)); */
} else {
Debugger::say("FAILED to get attachment: cannot fopen the file.");
return false;
}
Debugger::say("Completed getting attachment.");
return true;
} else {
Debugger::say("FAILED to get attachment: not connected.");
return false;
}
}
function _setHeader($ch, $header) {
if (preg_match("/Content-Length: (\d*)/i",$header,$matches)) {
if ($this->send_headers) header("Content-Length: ".$matches[1]);
//Debugger::say("Content-Length: ".$matches[1]);
$this->attach_info['size'] = $matches[1];
} elseif (preg_match("/Content-Disposition:.*?filename=\"(.*)\"/i",$header,$matches)) {
//if ($this->send_headers) header("Content-Disposition: ".$matches[1]);
$this->attach_info['filename'] = $matches[1];
} elseif (preg_match("/Content-Type: ([^; ]*)/i",$header,$matches)) {
if ($this->send_headers) header("Content-Type: ".$matches[1]);
$this->attach_info['type'] = $matches[1];
//Debugger::say("Content-Length: ".$matches[1]);
}
//print $header;
$this->headers[] = $header;
//Debugger::say(print_r($this->headers,true));
//Debugger::say(print_r($this,true));
return strlen($header);
}
/**
* Dump everything to output.
*
* This is a "low-level" method. Use the method {@link GMailer::fetchBox()} to fetch standard contents from Gmail.
*
* @return string Everything received from Gmail.
* @param string $query URL query string.
*/
function dump($query) {
if ($this->isConnected() == true) {
Debugger::say("Dumping...");
$query .= $this->proxy_defeat(); // to fool proxy
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
$this->GM_LNK_GMAIL."?ik=&search=inbox&view=tl&start=0&init=1".$this->proxy_defeat(),
'get', "", "noheader", ""
);
Debugger::say("Finished dumping ".strlen($this->gmail_data)." bytes.");
return $this->gmail_data;
} else { // not logged in yet
Debugger::say("FAILED to dump: not connected.");
return "";
}
}
/**
* Send Gmail. Or save a draft email.
*
* Examples:
* <code>
* <?php
* // Simplest usage: send a new mail to one person:
* $gmailer->send("hide@address.com", "Hello World", "Cool!\r\nFirst mail!");
*
* // More than one recipients. And with CC:
* $gmailer->send("hide@address.com, hide@address.com",
* "Hello World",
* "This is second mail.",
* "carbon-hide@address.com");
*
* // With file attachment
* $gmailer->send("hide@address.com",
* "Your file",
* "Here you are!",
* "", "", "", "",
* array("path/to/file.zip", "path/to/another/file.tar.gz"));
*
* // more examples...
* ? >
* </code>
*
* @since 9 September 2005
* @return bool Success or not. If returned false, please check {@link GMailer::$return_status} or {@link GMailer::lastActionStatus()} for error message.
* @param string $to Recipient's address. Separated by comma for multiple recipients.
* @param string $subj Subject line of email.
* @param string $body Message body of email.
* @param string $cc Address for carbon-copy (CC). Separated by comma for multiple recipients. $cc = "" for none.
* @param string $bcc Address for blind-carbon-copy (BCC). Separated by comma for multiple recipients. $bcc = "" for none.
* @param string $mid Message ID of the replying email. $mid = "" if this is a newly composed email.
* @param string $tid Conversation (thread) ID of the replying email. $tid = "" if this is a newly composed email.
* @param string[] $files File names of files to be attached.
* @param bool $draft Indicate this email is saved as draft, or not.
* @param string $orig_df If this email is saved as a <i>modified</i> draft, then set $orig_df as the draft ID of the original draft.
* @param bool $is_html HTML/RTF-formatted mail, or not.
* @param array $attachments Attachments (forwards) in the form of 0_messageIDthatContainedTheAttachment_attachmentID (e.g. 0_17ab83d2f68n2b_0.1 , 0_17ab83d2f68n2b_0.2)
* @param string $from Send mail as this email address (personality). $from = "" to use default address in your settings. Note: the "default" behavior changed on 29 April 2006. Note: you will NOT send your mail successfully if you do not register this address in your Gmail settings panel.
*/
function send($to, $subj, $body, $cc="", $bcc="", $mid="", $tid="", $files=0, $draft=false, $orig_df="", $is_html=0, $from="", $attachments = array()) {
if ($this->isConnected()) {
$postdata = array();
if ($draft == true) {
$postdata["view"] = "sd";
} else {
$postdata["view"] = "sm";
}
$postdata["draft"] = $orig_df;
$postdata["rm"] = $mid;
$postdata["th"] = $tid;
$postdata["at"] = $this->at_value();
// These are in the POST form, but do not know what they are
// or what their values should be
// Send works ok despite these being left out.
//$postdata["wid"] = 8;
//$postdata["jsid"] = xxxxxxxxxx;
//$postdata["ov"] = "";
//$postdata["cmid"] = 1;
if (strlen($from) > 0) {
$postdata["from"] = $from;
}
$postdata["to"] = stripslashes($to);
$postdata["cc"] = stripslashes($cc);
$postdata["bcc"] = stripslashes($bcc);
$postdata["subject"] = stripslashes($subj);
$postdata["ishtml"] = ($is_html) ? 1 : 0;
$postdata["msgbody"] = stripslashes($body);
// Added attachment/forward support; by Neerav; 22 Oct 2005
// should be POST, but we fake it in GET
$getdata = "";
if (count($attachments) > 0) {
for ($i=0; $i<count($attachments); $i++) {
$getdata .= "&attach=".$attachments[$i];
}
}
$new_attach = 0;
if (is_array($files)) {
// an array of files supplied
$new_attach = count($files);
for ($i = 0; $i < $new_attach; $i++) {
$postdata["file".$i] = "@".realpath($files[$i]);
}
} elseif ($files != 0) {
// only one file attachment supplied
$new_attach = 1;
$postdata["file"] = "@".realpath($files);
}
//echo $postdata;
// hosted domains need a different url; Added by Neerav; 15 Feb 2007
if ($this->domain) {
// First, get the GMAIL_HELP and/or GMAIL_AT cookies which are now REQUIRED yet strangely missing (7 Feb 2007)
if (strpos($this->cookie_str, "GMAIL_HELP") === false) {
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL_A."?view=page&name=htmlcompose",
$this->GM_LNK_GMAIL_A."?&view=page&name=gp",
'get',
""
);
if (preg_match("/Location:\s*((http(s)?:\/\/)?(.*?))\n/",$this->gmail_data,$matches)) {
if (strpos($matches[1],"http") !== 0) {
// be prepared for relative url
$host_redir_url = "https://www.google.com".$matches[1];
} else {
// currently fully qualified url
$host_redir_url = $matches[1];
}
$this->gmail_data = GMailer::execute_curl(
$host_redir_url,
$this->GM_LNK_GMAIL_A."?view=page&name=htmlcompose",
'get',
""
);
}
}
//Debugger::say("pre sending message: ".print_r($this->gmail_data,true));
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL_A."?search=inbox&newatt=".$new_attach."&rematt=0".$getdata,
((isset($host_redir_url)) ? $host_redir_url : "&view=cv&search=inbox&th=".$tid."&qt=".$this->proxy_defeat("nodash")),
'post',
$postdata
);
// non-hosted domain
} else {
// Changed to add attachment/forward support ($getdata); by Neerav; 22 Oct 2005
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?&search=inbox&qt=&cmid=&newatt=".$new_attach."&rematt=0".$getdata,
$this->GM_LNK_GMAIL."?&view=cv&search=inbox&th=".$tid/* ."&lvp=4&cvp=1" */."&qt=".$this->proxy_defeat("nodash"),
'post',
$postdata
);
}
GMailer::parse_gmail_response($this->gmail_data);
// Added by Neerav; 12 July 2005
$status = (isset($this->raw["sr"][2])) ? $this->raw["sr"][2] : false;
$a = array(
"action" => "send email",
// $this->raw["sr"][1] // what is this?? // always 1
"status" => ($status ? "success" : "failed"),
"message" => (isset($this->raw["sr"][3]) ? $this->raw["sr"][3] : ""),
"thread_id" => (isset($this->raw["sr"][4]) ? $this->raw["sr"][4] : ""),
// $this->raw["sr"][5] // what is this?? // always 0
// $this->raw["sr"][6] // what is this?? // always an empty array
// $this->raw["sr"][7] // what is this?? // always 0
// $this->raw["sr"][8] // what is this?? // always 0
// $this->raw["sr"][9] // what is this?? // always 0
// $this->raw["sr"][10] // what is this?? // always blank (or false)
// $this->raw["sr"][11] // what is this?? // some kind of message/server id, but doesn't match any header
// $this->raw["sr"][12] // what is this?? // always 0
"sent_num" => ((isset($this->raw["aa"][1])) ? count($this->raw["aa"][1]) : 0)
);
array_unshift($this->return_status, $a);
// Changed by Neerav; 12 July 2005
return $status;
} else {
// Added by Neerav; 12 July 2005
$a = array(
"action" => "send email",
"status" => "failed",
"message" => "libgmailer: not connected.",
"thread_id" => $tid,
"sent_num" => 0
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Perform action on messages.
*
* Examples:
* <code>
* <?php
* // Apply label to $message_id
* $gmailer->performAction(GM_ACT_APPLYLABEL, $message_id, "my_label");
*
* // Star $message_id
* $gmailer->performAction(GM_ACT_STAR, $message_id);
*
* // more examples...
* ? >
* </code>
*
* @return bool Success or not. If returned false, please check {@link GMailer::$return_status} or {@link GMailer::lastActionStatus()} for error message.
Additional return: Gmail returns a full datapack in response
* @param constant $act Action to be performed.
* @param string[] $id Message ID. If the action is GM_ACT_EMPTYSPAM or GM_ACT_EMPTYTRASH, supply the $snapshot->mailbox_state value
* @param string $para Action's parameter:
* 1. {@link GM_ACT_APPLYLABEL}, {@link GM_ACT_REMOVELABEL}: Name of the label.
* @param string[] $mailbox Standard/Label mailbox name. If this left out, actions will only work on messages in the Inbox.
*/
function performAction($act, $id, $para="", $mailbox="") {
// Fixed (un)trash, added delTrashedMsgs action; by Neerav; 27 Feb 2006
/* $this->gmail_data = GMailer::execute_curl( */
/* $this->GM_LNK_GMAIL."?".$link */
/* $this->GM_LNK_GMAIL."?".$referrer, */
/* 'post', */
/* $postdata */
/* ); */
if ($this->isConnected()) {
$postdata = "";
$query = "";
$referrer = $this->GM_LNK_GMAIL."?ik=&search=inbox&view=tl&start=0&init=1".$this->proxy_defeat();
$action_codes = array(
"ib", // nothing / placeholder
"ac_", // GM_ACT_APPLYLABEL
"rc_", // GM_ACT_REMOVELABEL
"st", // GM_ACT_STAR
"xst", // GM_ACT_UNSTAR
"sp", // GM_ACT_SPAM
"us", // GM_ACT_UNSPAM
"rd", // GM_ACT_READ
"ur", // GM_ACT_UNREAD
"tr", // GM_ACT_TRASH
"dl", // GM_ACT_DELFOREVER
"rc_^i", // GM_ACT_ARCHIVE
"ib", // GM_ACT_INBOX
"ib", // GM_ACT_UNTRASH
"dd", // GM_ACT_UNDRAFT
"dm", // GM_ACT_TRASHMSG
"dl", // GM_ACT_DELSPAM
"dl", // GM_ACT_DELTRASHED
"rtr", // GM_ACT_UNTRASHMSG
"dt" // GM_ACT_DELTRASHEDMSGS
);
if ($act == GM_ACT_DELFOREVER)
$this->performAction(GM_ACT_TRASH, $id, 0, $mailbox); // trash it before
//$postdata .= "ik=".$this->cookie_ik_str;
$postdata .= "&act=";
$postdata .= (isset($action_codes[$act])) ? $action_codes[$act] : $action_codes[GM_ACT_INBOX];
if ($act == GM_ACT_APPLYLABEL || $act == GM_ACT_REMOVELABEL) {
$postdata .= $para;
}
$postdata .= "&at=".$this->at_value();
if ($act == GM_ACT_TRASHMSG || $act == GM_ACT_UNTRASHMSG) {
$postdata .= "&m=".$id;
} else {
if (is_array($id)) {
foreach ($id as $t) {
$postdata .= "&t=".$t;
}
} else {
$postdata .= "&t=".$id;
}
if ($act != GM_ACT_DELTRASHEDMSGS) {
$postdata .= "&vp=";
$postdata .= "&msq="; // Added by Neerav; 25 Nov 2005
$postdata .= "&ba=false"; // Added by Neerav; 25 Nov 2005
}
}
if ($act == GM_ACT_UNTRASH || $act == GM_ACT_DELFOREVER || $act == GM_ACT_DELTRASHED || $act == GM_ACT_EMPTYTRASH) {
$query .= "&search=trash";
} elseif ($act == GM_ACT_DELSPAM || $act == GM_ACT_EMPTYSPAM) {
$query .= "&search=spam";
} elseif ($mailbox != "") {
switch ($mailbox) {
case "inbox": $box_type = "std"; break;
case "starred": $box_type = "std"; break;
case "sent": $box_type = "std"; break;
case "drafts": $box_type = "std"; break;
case "all": $box_type = "std"; break;
case "spam": $box_type = "std"; break;
case "trash": $box_type = "std"; break;
case "chats": $box_type = "std"; break;
default: $box_type = "label"; break;
}
if ($box_type == "std") {
$query = "&search=".$mailbox;
} else {
$query = "&search=cat&cat=".urlencode($mailbox);
$referrer = $this->GM_LNK_GMAIL."?&search=cat&cat=".urlencode($mailbox)."&view=tl&start=0".$this->proxy_defeat();
}
} else {
$query = "&search=query&q=";
}
if ($act == GM_ACT_TRASHMSG || $act == GM_ACT_UNTRASHMSG || $act == GM_ACT_DELTRASHEDMSGS) {
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?"."&qt=".$query."&view=up".$postdata.$this->proxy_defeat(),
"",
'get'
);
} elseif ($act == GM_ACT_EMPTYSPAM || $act == GM_ACT_EMPTYTRASH) {
$refer = $this->GM_LNK_GMAIL."?";
if ($act == GM_ACT_EMPTYSPAM) {
$refer .= "&search=spam";
} else {
$refer .= "&search=trash";
}
$refer .= "&view=tl&start=0".$this->proxy_defeat();
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query."&view=tl&start=0".$this->proxy_defeat()."&ba=1&act=dl".(($id != NULL and $id != "") ? "&msq=".$id: '')."&at=".$this->at_value(),
$refer,
'get'
);
} else {
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query."&view=tl&start=0",
$referrer,
'post',
$postdata
);
}
GMailer::parse_gmail_response($this->gmail_data);
// Added additional return info; by Neerav; 13 July 2005
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "message action",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
// Added by Neerav; 12 July 2005
$a = array(
"action" => "message action",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* @return bool Success or not.
* @desc Recover session information.
*/
function getSessionFromBrowser() {
Debugger::say("Start getting session from browser...");
if (!$this->use_session) {
return $this->getCookieFromBrowser();
}
// Changed to support IK; by Neerav; 13 July 2005
// Last modified by Neerav; 14 Aug 2005
if (isset($_SESSION[GM_COOKIE_KEY])) {
$this->cookie_str = base64_decode($_SESSION[GM_COOKIE_KEY]);
Debugger::say("Completed getting session from server: ".$this->cookie_str);
if (isset($_SESSION['id_key'])) {
$this->cookie_ik_str = $_SESSION['id_key'];
Debugger::say("Completed getting ik from server: ".$this->cookie_ik_str);
} else {
Debugger::say("FAILED to read id_key from server.");
}
return true;
} else {
Debugger::say("FAILED to read ".GM_COOKIE_KEY." or ".'id_key'." from server.");
/* Debugger::say("FAILED to read cookie ".GM_COOKIE_KEY." from browser."); */
return false;
}
}
/**
* @return bool Success or not.
* @desc Get cookies from browser.
*/
function getCookieFromBrowser() {
Debugger::say("Start getting cookie from browser...");
if (!isset($_COOKIE)) {
Debugger::say("FAILED to get any cookie from browser.");
return false;
}
if (count($_COOKIE) == 0) {
Debugger::say("FAILED to get non-empty cookie array from browser.");
return false;
}
// Changed to support IK cookie; by Neerav; 8 July 2005
// Disabled IK cookie requirement
//if (isset($_COOKIE[GM_COOKIE_KEY]) and isset($_COOKIE[GM_COOKIE_IK_KEY])) {
if (isset($_COOKIE[GM_COOKIE_KEY]) and $_COOKIE[GM_COOKIE_KEY]) {
$this->cookie_str = base64_decode($_COOKIE[GM_COOKIE_KEY]);
Debugger::say("Completed getting cookie from browser: ".$this->cookie_str);
if (isset($_COOKIE[GM_COOKIE_IK_KEY]) and $_COOKIE[GM_COOKIE_IK_KEY]) {
$this->cookie_ik_str = base64_decode($_COOKIE[GM_COOKIE_IK_KEY]);
Debugger::say("Completed getting ik cookie from browser: ".$this->cookie_ik_str);
}
return true;
} else {
//Debugger::say("FAILED to read cookie ".GM_COOKIE_KEY." or ".GM_COOKIE_IK_KEY." from browser.");
Debugger::say("FAILED to read cookie ".GM_COOKIE_KEY." from browser.");
return false;
}
}
/**
* @return bool Success or not.
* @desc Save session data.
*/
// Replaced Debugger calls with detailed status info; by Neerav; 2 May 2006
function saveSessionToBrowser() {
if ($this->isConnected()) {
if (!$this->use_session)
return $this->saveCookieToBrowser();
$_SESSION[GM_COOKIE_KEY] = base64_encode($this->cookie_str);
$a = array(
"action" => "save cookie to server",
"status" => "success",
"message" => "Saved cookie to server"
);
array_unshift($this->return_status, $a);
return true;
}
$a = array(
"action" => "save cookie to server",
"status" => "failed",
"message" => "not connected"
);
array_unshift($this->return_status, $a);
return false;
}
/**
* @return bool Success or not.
* @desc Save (send) cookies to browser.
*/
// Replaced Debugger calls with detailed status info; by Neerav; 2 May 2006
function saveCookieToBrowser() {
if ($this->isConnected()) {
if (strpos($_SERVER["HTTP_HOST"],":"))
$domain = substr($_SERVER["HTTP_HOST"],0,strpos($_SERVER["HTTP_HOST"],":"));
else
$domain = $_SERVER["HTTP_HOST"];
// Fixed cookie expiration bug; by Neerav; 1 May 2006
//header("Set-Cookie: ".GM_COOKIE_KEY."=".base64_encode($this->cookie_str)."; Domain=".$domain.";");
setcookie(GM_COOKIE_KEY, base64_encode($this->cookie_str), time()+GM_COOKIE_TTL, "", $domain);
$a = array(
"action" => "save gmail cookie to browser",
"status" => "success",
"message" => "Saved cookie with domain: ".$domain
);
array_unshift($this->return_status, $a);
return true;
}
$a = array(
"action" => "save gmail cookie to browser",
"status" => "failed",
"message" => "not connected"
);
array_unshift($this->return_status, $a);
return false;
}
/**
* @return bool Success or not.
* @desc Remove all session information related to Gmailer.
*/
// Replaced Debugger calls with detailed status info; by Neerav; 2 May 2006
function removeSessionFromBrowser() {
if (!$this->use_session)
return $this->removeCookieFromBrowser();
// Changed/Added by Neerav; 6 July 2005
// determines whether session should be preserved or normally destroyed
if (GM_USE_LIB_AS_MODULE) {
// if this lib is used as a Gmail module in some other app (e.g.
// "online office"), don't destroy session
// Let's unset session variables
if (isset($_SESSION[GM_COOKIE_KEY])) unset($_SESSION[GM_COOKIE_KEY]);
if (isset($_SESSION['id_key'])) unset($_SESSION['id_key']);
$a = array(
"action" => "clear session from browser",
"status" => "success",
"message" => "Cleared libgmailer related session info. Session preserved for other use."
);
array_unshift($this->return_status, $a);
} else {
// otherwise (normal) unset and destroy session
$cookie_path = str_replace(DIRECTORY_SEPARATOR,"/",dirname($_SERVER['SCRIPT_NAME']))."/";
if ($cookie_path == "//") $cookie_path = "/";
@ini_set("session.cookie_path",$cookie_path);
@session_unset();
@session_destroy();
/* @session_write_close(); */
$a = array(
"action" => "destroy session from browser",
"status" => "success",
"message" => "Removed session: ".GM_COOKIE_KEY.". Finished removing session from browser."
);
array_unshift($this->return_status, $a);
}
return true;
}
/**
* @return bool
* @desc Remove all related cookies stored in browser.
*/
// Replaced Debugger calls with detailed status info; by Neerav; 2 May 2006
function removeCookieFromBrowser() {
if (isset($_COOKIE)) {
// Changed to include IK cookie; by Neerav; 8 July 2005
if (isset($_COOKIE[GM_COOKIE_KEY]) or isset($_COOKIE[GM_COOKIE_IK_KEY])) {
// libgmailer cookies exist
if (strpos($_SERVER["HTTP_HOST"],":"))
$domain = substr($_SERVER["HTTP_HOST"],0,strpos($_SERVER["HTTP_HOST"],":"));
else
$domain = $_SERVER["HTTP_HOST"];
/* header("Set-Cookie: ".GM_COOKIE_KEY."=0; Discard; Domain=".$domain.";"); */
/* header("Set-Cookie: ".GM_COOKIE_IK_KEY."=0; Discard; Domain=".$domain.";"); */
// Fixed cookie expiration bug; by Neerav; 1 May 2006
setcookie(GM_COOKIE_KEY, "", 1, "", $domain);
setcookie(GM_COOKIE_IK_KEY, "", 1, "", $domain);
$a = array(
"action" => "remove cookies",
"status" => "success",
"message" => "Removed cookies: ".GM_COOKIE_KEY." and ".GM_COOKIE_IK_KEY."with domain: ".$domain
);
array_unshift($this->return_status, $a);
return true;
} else {
$a = array(
"action" => "remove cookies",
"status" => "failed",
"message" => "Cannot find libgmailer cookies: ".GM_COOKIE_KEY." or ".GM_COOKIE_IK_KEY
);
array_unshift($this->return_status, $a);
return false;
}
} else {
$a = array(
"action" => "remove cookies",
"status" => "failed",
"message" => "Cannot find any cookie from browser."
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* @return void
* @desc Disconnect from Gmail.
*/
function disconnect() {
Debugger::say("Start disconnecting...");
/** logout from mail.google.com too **/
$this->gmail_data = GMailer::execute_curl(
// Updated by Neerav; 28 June 2005
$this->GM_LNK_GMAIL."?logout&hl=en".$this->proxy_defeat("nodash"),
$this->GM_LNK_GMAIL."?&ik=&search=inbox&view=tl&start=0&init=1".$this->proxy_defeat("nodash"),
'get'
);
//GMailer::parse_gmail_response($this->gmail_data);
//Debugger::say("logout: ".$this->gmail_data);
Debugger::say("Logged-out from GMail.");
$this->removeSessionFromBrowser();
$this->cookie_str = "";
$this->cookie_ik_str = ""; // Added to support IK; by Neerav; 13 July 2005
Debugger::say("Completed disconnecting.");
}
/**
* Get {@link GMailSnapshot} by type.
*
* Examples:
* <code>
* <?php
* // For "Inbox"
* $gmailer->fetchBox(GM_STANDARD, "inbox", 0);
* $snapshot = $gmailer->getSnapshot(GM_STANDARD);
*
* // For conversation
* $gmailer->fetchBox(GM_CONVERSATION, $thread_id, 0);
* $snapshot = $gmailer->getSnapshot(GM_CONVERSATION);
* ? >
* </code>
*
* @return GMailSnapshot
* @param constant $type
* @see GMailSnapshot
* @see GM_STANDARD, GM_LABEL, GM_CONVERSATION, GM_QUERY, GM_PREFERENCE, GM_CONTACT
*/
function getSnapshot($type) {
// Comment by Neerav; 9 July 2005
// $type slowly will be made unnecessary as we move towards included all response
// fields in the snapshot
if (!($type & (GM_STANDARD|GM_LABEL|GM_CONVERSATION|GM_QUERY|GM_PREFERENCE|GM_CONTACT))) {
// if not specified, assume normal by default
$type = GM_STANDARD;
}
// Changed by Neerav; use_session Fix by Dave DeLong <daveATdavedelongDOTcom>; 9 July 2005
// Added $this->gmail_data to handle http errors; by Neerav; 16 Sept 2005
return new GMailSnapshot($type, $this->raw, $this->use_session,$this->gmail_data);
}
/**
* Send an invite
*
* @return bool Success or not. Note that it will still be true even if $email is an illegal address.
* @param string $email
* @desc Send Gmail invite to $email
*/
function invite($email) {
// Invalid feature for hosted domains; Added by Neerav; 9 June 2006
if ($this->domain) {
$a = array(
"action" => "invite",
"status" => "failed",
"message" => "libgmailer: feature not available for hosted domains"
);
array_unshift($this->return_status, $a);
return false;
}
if ($this->isConnected()) {
$postdata = "act=ii&em=".urlencode($email);
$postdata .= "&at=".$this->at_value();
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?view=ii",
$this->GM_LNK_INVITE_REFER,
'post',
$postdata
);
// Added status message parsing and return; by Neerav; 6 Aug 2005
GMailer::parse_gmail_response($this->gmail_data);
// Added by Neerav; 6 Aug 2005
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "invite",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
// Added by Neerav; 6 Aug 2005
$a = array(
"action" => "invite",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Get names of standard boxes.
*
* @static
* @return string[]
* @deprecated
*/
function getStandardBox() {
return array("Inbox","Starred","Sent","Drafts","All","Spam","Trash");
}
/**
* Get raw packet Gmailer::$raw
*
* @access private
* @return mixed
*/
function dump_raw() {
return $this->raw;
}
/**
* Get full contents of $gmail_data (complete response from Gmail)
*
* @access private
* @return mixed
* @author Neerav
* @since 13 Aug 2005
*/
function debug_gmail_response() {
return $this->gmail_data;
}
/**
* cURL "helper" for proxy.
*
* @access private
* @return void
* @param curl_descriptor $cc
*/
function CURL_PROXY(&$cc) {
if (strlen($this->proxy_host) > 0) {
curl_setopt($cc, CURLOPT_PROXY, $this->proxy_host);
if (strlen($this->proxy_auth) > 0)
curl_setopt($cc, CURLOPT_PROXYUSERPWD, $this->proxy_auth);
}
}
/**
* Extract cookies from HTTP header.
*
* @return string Cookies string
* @param string $header HTTP header
* @access private
* @static
*/
function get_cookies($header) {
// addition of cookie array; Neerav; 15 Mar 2007
$match = "";
$cookie = "";
$cookie_array = array();
preg_match_all('!Set-Cookie: ([^;\s]+)($|;)!', $header, $match);
foreach ($match[1] as $val) {
$name = "";
$value = "";
// Skip over undesired cookies which were causing problems; by Neerav; 4 Apr 2006
if (strpos($val,"GoogleAccountsLocale_session") !== false) continue;
if ($val{0} == '=') continue;
$equal = strpos($val,"=");
$name = substr($val,0,$equal);
$value = substr($val,$equal+1);
//Debugger::say("orig: $val\ncookie: $name:$value");
if ($value == "EXPIRED") {
if (isset($cookie_array["$name"])) unset($cookie_array["$name"]);
} else {
$cookie_array["$name"] = $value;
}
}
foreach($cookie_array as $name => $value) {
$cookie .= $name."=".$value."; ";
}
/* $debug = "get_cookies()\n\n"; */
/* $debug .= "New cookies: ".print_r($match,true)."\n\n"; */
/* $debug .= "cookie array: ".print_r($cookie_array,true)."\n\n"; */
/* $debug .= "cookie string: ".print_r($cookie,true)."\n\n"; */
/* Debugger::say($debug); */
return substr($cookie, 0, -2);
}
/**
* Attempt to set Gmail cookies for direct access
*
* @return none
* @param none
* @access public
* @static
*/
/* // added 27 Apr 2007; Neerav */
/* function exportCookiesToGmail() { */
/* $cookie_array = explode("; ", $this->cookie_str); */
/* foreach($cookie_array as $index => $value) { */
/* $equal = strpos($value, "="); */
/* $cname = substr(trim($value),0,$equal); */
/* //if ($cname == "TZ") continue; */
/* $cvalue = substr(trim($value),$equal+1); */
/* */
/* if ($cname == "SID") { */
/* header("Location: http://mail.google.com/mail/?Auth=".$cvalue); */
/* exit; */
/* } */
/* setcookie("$cname", "$cvalue", time()+100000, "/mail/", "google.com"); */
/* } */
/* setcookie("test", "test", time()+100000, "/", "gmobtest.sayni.net"); */
/* } */
/**
* Process Gmail data packets.
*
* @access private
* @static
* @return mixed[]
* @param string $input
* @param int& $offset
*/
function parse_data_packet($input, &$offset) {
$output = array();
// state variables
$isQuoted = false; // track when we are inside quotes
$dataHold = ""; // temporary data container
$lastCharacter = " ";
// walk through the entire string
for($i=1; $i < strlen($input); $i++) {
switch($input[$i]) {
case "[": // handle start of array marker
if(!$isQuoted) {
// recurse any nested arrays
array_push($output, GMailer::parse_data_packet(substr($input,$i), $offset));
// the returning recursive function write out the total length of the characters consumed
$i += $offset;
// assume that the last character is a closing bracket
$lastCharacter = "]";
} else {
$dataHold .= "[";
}
break;
case "]": // handle end of array marker
if(!$isQuoted) {
if($dataHold != "") {
array_push($output, $dataHold);
}
// determine total number of characters consumed (write to reference)
$offset = $i;
return $output;
} else {
$dataHold .= "]";
break;
}
case '"': // toggle quoted state
if($isQuoted) {
$isQuoted = false;
} else {
$isQuoted = true;
$lastCharacter = '"';
}
break;
case ',': // find end of element marker and add to array
if(!$isQuoted) {
if($dataHold != "") { // this is to filter out adding extra elements after an empty array
array_push($output, $dataHold);
$dataHold = "";
} else if($lastCharacter == '"') { // this is to catch empty strings
array_push($output, "");
}
} else {
$dataHold .= ",";
}
break;
case '\\':
if ($i < strlen($input) - 1) {
switch($input[$i+1]) {
case "\\": /* for the case \\ */
// Added by Neerav; June 2005
// strings that END in \ are now handled properly
if ($i < strlen($input) - 2) {
switch($input[$i+2]) {
case '"': /* for the case \\" */
$dataHold .= '\\';
$lastCharacter = '\\"';
$i += 1;
break;
case "'": /* for the case \\' */
$dataHold .= "\\";
$lastCharacter = "\\'";
$i += 1;
break;
default:
}
} else {
$dataHold .= '\\';
$lastCharacter = '\\';
}
break;
case '"': /* for the case \" */
$dataHold .= '"';
$lastCharacter = '\"';
$i += 1;
break;
case "'": /* for the case \' */
$dataHold .= "'";
$lastCharacter = "\'";
$i += 1;
break;
case "n": /* for the case \n */
$dataHold .= "\n";
$lastCharacter = "\n";
$i += 1;
break;
case "r": /* for the case \r */
$dataHold .= "\r";
$lastCharacter = "\r";
$i += 1;
break;
case "t": /* for the case \t */
$dataHold .= "\t";
$lastCharacter = "\t";
$i += 1;
break;
default:
}
}
break;
default: // regular characters are added to the data container
$dataHold .= $input[$i];
break;
}
}
return $output;
}
/**
* Create/edit contact.
*
*Examples:
*<code>
*<?php
* // Add a new one
* $gmailer->editContact(-1,
* "John",
* "hide@address.com",
* "Supervisor of project X",
* );
*
* // Add a new one with lots of details
* // each detail can be supplied as:
* // this method is preferred since libgmailer presents existing contacts in this format
* array("type" => "phone", "info" => "123-45678"),
*
* $gmailer->editContact(
* -1,
* "Mike G. Stone",
* "hide@address.com",
* "Mike is a great guy!",
* array(
* array(
* array("type" => "phone" , "info" => "123-45678"),
* array("type" => "mobile" , "info" => "987-65432"),
* array("type" => "fax" , "info" => "111-11111"),
* array("type" => "pager" , "info" => "222-22222"),
* array("type" => "im" , "info" => "34343434"),
* array("type" => "company" , "info" => "22nd Century Fox"),
* array("type" => "position" , "info" => "CEO"),
* array("type" => "other" , "info" => "Great football player!"),
* array("type" => "address" , "info" => "1 Fox Rd"),
* array("type" => "detail_name" , "info" => "Work")
* ),
* array(
* array("type" => "phone" , "info"=> "1-23-4567"),
* array("type" => "mobile" , "info"=> "9-87-6543"),
* array("type" => "email" , "info"=> "hide@address.com"),
* array("type" => "im" , "info"=> "stonymike (yahoo)"),
* array("type" => "im" , "info"=> "hide@address.com"),
* array("type" => "other" , "info"=> "Has huge collection of World Cup t-shirts"),
* array("type" => "address" , "info"=> "1 Elm Street"),
* array("type" => "detail_name" , "info"=> "Home")
* )
* )
* );
*
* // Modified an existing one
* $gmailer->editContact($contact_id,
* "Old Name", // or changed name
* "hide@address.com", // or original_mail if only name or notes are changed
* "Old notes", // or edited notes
* array("other contact details") // if you leave this out, ALL DETAILS WILL BE LOST
* // IF THIS IS NOT CHANGED, IT MUST BE CACHED AND SUBMITTED TO THIS FUNCTION
* );
* ? >
* </code>
*
* NOTE: You must supply the old name even if you are not going to modify it, or it will
* be changed to empty!
*
* Note: You must supply the CONTACT DETAILS even if you are not going to modify it, or they will
* be LOST FOREVER!
*
* @return bool Success or not.
Extended return: array(bool success/fail, string message, string contact_id)
* @param string $contact_id Contact ID for editing an existing one, or -1 for creating a new one
* @param string $name Name
* @param string $email Email address
* @param string $notes Notes
* @param mixed[][] $details Detailed information
* @author Neerav
* @since 15 Jun 2005
*/
function editContact($contact_id, $name, $email, $notes, $details=array()) {
if ($this->isConnected()) {
$postdata = array();
$postdata["act"] = "ec";
$postdata["ct_id"] = "$contact_id";
$postdata["ct_nm"] = $name;
$postdata["ct_em"] = $email;
$postdata["ctf_n"] = $notes;
// Added by Neerav; 1 July 2005
// contact details
if (count($details) > 0) {
$i = 0; // the detail number
$det_num = '00'; // detail number padded to 2 numbers for gmail
foreach ($details as $detail1) {
$postdata["ctsn_"."$det_num"] = "Unnamed"; // default name if none defined later
$address = ""; // default address if none defined later
$k = 0; // the field number supplied to Gmail
$field_num = '00'; // must be padded to 2 numbers for gmail
foreach ($detail1 as $indexval2 => $detail) {
/* // added to accept the OLD format/example; by Neerav; 6 May 2007 */
/* if (!is_array($detail)) { */
/* $temp = $detail; */
/* $detail = array(); */
/* $detail["info"] = $temp; */
/* $detail["type"] = $indexval2; */
/* } */
//Debugger::say("edit contact detail: ".print_r($detail,true));
$field_type = "";
switch (strtolower($detail["type"])) {
case "phone": $field_type = "p"; break;
case "email": $field_type = "e"; break;
case "mobile": $field_type = "m"; break;
case "fax": $field_type = "f"; break;
case "pager": $field_type = "b"; break;
case "im": $field_type = "i"; break;
case "company": $field_type = "d"; break;
case "position": $field_type = "t"; break; // t = title
case "other": $field_type = "o"; break;
case "address": $field_type = "a"; break;
case "detail_name": $field_type = "xyz"; break;
default: $field_type = "o"; break; // default to other
//default: $field_type = $detail["type"]; break; // default to the unknown detail
}
if ($field_type == "xyz") {
$postdata["ctsn_"."$det_num"] = $detail["info"];
} elseif ($field_type == "a") {
$address = $detail["info"];
} else {
// e.g. ctsf_00_00_p for phone
$postdata["ctsf_"."$det_num"."_"."$field_num"."_"."$field_type"] = $detail["info"];
// increments the field number and pads it
$k++;
$field_num = str_pad($k, 2, '0', STR_PAD_LEFT);
}
}
// Address field needs to be last
// if more than one address was given, the last one found will be used
if ($address != "") $postdata["ctsf_"."$det_num"."_"."$field_num"."_a"] = $address;
// increment detail number
$i++;
$det_num = str_pad($i, 2, '0', STR_PAD_LEFT);
}
}
$postdata["at"] = $this->at_value();
//Debugger::say("edit contact post: ".print_r($postdata,true));
//Debugger::say("edit contact post: ".print_r($details,true));
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?view=up",
$this->GM_LNK_GMAIL."?&search=contacts&ct_id=1&cvm=2&view=ct",
'post',
$postdata
);
GMailer::parse_gmail_response($this->gmail_data);
$orig_contact_id = $contact_id;
if ($orig_contact_id == -1 and $this->raw["ar"][1]) {
if (isset($this->raw["cov"][1][1])) $contact_id = $this->raw["cov"][1][1];
elseif (isset($this->raw["a"][1][1])) $contact_id = $this->raw["a"][1][1];
elseif (isset($this->raw["cl"][1][1])) $contact_id = $this->raw["cl"][1][1];
}
$status = $this->raw["ar"][1];
$a = array(
"action" => (($orig_contact_id == -1) ? "add contact": "edit contact"),
"status" => (($status) ? "success" : "failed"),
"message" => $this->raw["ar"][2],
"contact_id" => "$contact_id"
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => (($orig_contact_id == -1) ? "add contact": "edit contact"),
"status" => "failed",
"message" => "libgmailer: not connected",
"contact_id" => "$contact_id"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Add message's senders to contact list.
*
* @return bool
* @param string $message_id Message ID
* @author Neerav
* @since 14 Aug 2005
*/
function addSenderToContact($message_id) {
if ($this->isConnected()) {
$query = "";
//$query .= "&ik=".$this->cookie_ik_str;
$query .= "&search=inbox";
$query .= "&view=up";
$query .= "&act=astc";
$query .= "&at=".$this->at_value();
$query .= "&m=".$message_id;
$query .= $this->proxy_defeat(); // to fool proxy
set_time_limit(150);
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $this->GM_LNK_GMAIL."?".$query);
// NOTE: DO NOT SEND REFERRER
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_HEADER, 1);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str);
$this->gmail_data = curl_exec($c);
GMailer::parse_gmail_response($this->gmail_data);
curl_close($c);
$a = array(
"action" => "add sender to contact list",
"status" => "success",
"message" => ""
);
array_unshift($this->return_status, $a);
return true;
} else {
$a = array(
"action" => "add sender to contact list",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Star/unstar a message quickly.
*
* @return bool Success or not.
Extended return: array(bool success/fail, string message, string contact_id)
* @param string $message_id
* @param string $action Either "star" or "unstar".
* @author Neerav
8 @since 18 Aug 2005
*/
function starMessageQuick($message_id, $action) {
if ($this->isConnected()) {
$query = "";
$query .= "&ik=".$this->cookie_ik_str;
$query .= "&search=inbox";
$query .= "&view=up";
if ($action == "star") {
$query .= "&act=st";
} else {
$query .= "&act=xst";
}
$query .= "&at=".$this->at_value();
$query .= "&m=".$message_id;
$query .= $this->proxy_defeat(); // to fool proxy
set_time_limit(150);
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $this->GM_LNK_GMAIL."?".$query);
// NOTE: DO NOT SEND REFERRER
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_HEADER, 1);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str);
$this->gmail_data = curl_exec($c);
GMailer::parse_gmail_response($this->gmail_data);
curl_close($c);
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "$action message",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "$action message",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Delete contacts.
*
* @return bool Success or not.
Extended return: array(bool success/fail, string message)
* @param string[] $id Contact ID to be deleted
* @author Neerav
* @since 15 Jun 2005
*/
function deleteContact($id) {
if ($this->isConnected()) {
$query = "";
if (is_array($id)) {
//Post: act=dc&at=xxxxx-xxxx&cl_nw=&cl_id=&cl_nm=&c=0&c=3d
$query .= "&act=dc&cl_nw=&cl_id=&cl_nm=";
foreach ($id as $indexval => $contact_id) {
$query .= "&c=".$contact_id;
}
} else {
$query .= "search=contacts";
$query .= "&ct_id=".$id;
$query .= "&cvm=2";
$query .= "&view=up";
$query .= "&act=dc";
}
$query .= "&at=".$this->at_value();
if (!is_array($id)) {
$query .= "&c=".$id;
$query .= $this->proxy_defeat(); // to fool proxy
}
if (is_array($id)) {
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?view=up",
$this->GM_LNK_GMAIL."?view=cl&search=contacts&pnl=a",
'post',
$query
);
} else {
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
$this->GM_LNK_GMAIL."?view=cl&search=contacts&pnl=a",
'get'
);
}
GMailer::parse_gmail_response($this->gmail_data);
$status = $this->raw["ar"][1];
$a = array(
"action" => "delete contact",
"status" => (($status) ? "success" : "failed"),
"message" => $this->raw["ar"][2]
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "delete contact",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Create, edit or remove label.
*
* @return bool Success or not.
Extended return: array (boolean success/fail, string message)
* @param string $label
* @param string $action Either "create", "remove" or "rename"
* @param string $renamelabel New name if renaming label
* @author Neerav
* @since 7 Jun 2005
*/
function editLabel($label, $action, $renamelabel) {
if ($this->isConnected()) {
//Debugger::say("ik value: ".$this->cookie_ik_str);
$postdata = "";
if ($action == "create") {
if (trim($label) == "") {
// throw an error if the label to create is blank; Neerav; 1 Feb 2007
$a = array(
"action" => "$action label",
"status" => "failed",
"message" => "libgmailer error: cannot create a blank label in editLabel()"
);
array_unshift($this->return_status, $a);
return false;
} else {
$postdata .= "&act=cc_".$label;
}
} elseif ($action == "rename") {
$postdata .= "&act=nc_".$label."^".$renamelabel;
} elseif ($action == "remove") {
$postdata .= "&act=dc_".$label;
} else {
// Changed by Neerav; 28 June 2005
// was boolean, now array(boolean,string)
$a = array(
"action" => "$action label",
"status" => "failed",
"message" => "libgmailer error: unknown action in editLabel()"
);
array_unshift($this->return_status, $a);
return false;
}
$postdata .= "&at=".$this->at_value();
if ($this->domain == "") {
$refer = $this->GM_LNK_GMAIL_HTTP."?&view=pr&pnl=l".$this->proxy_defeat();
$url = $this->GM_LNK_GMAIL_HTTP."?view=up";
} else {
// GAFYD
$postdata .= "&search=";
/* $refer = $this->GM_LNK_GMAIL_HTTP."?ik=".$_SESSION['id_key']."&view=pr&pnl=l&lm=m_prefs".$this->proxy_defeat(); */
$refer = $this->GM_LNK_GMAIL_HTTP."?view=pr&pnl=l&lm=m_prefs".$this->proxy_defeat();
$url = $this->GM_LNK_GMAIL_A."?view=up";
}
//Debugger::say($this->GM_LNK_GMAIL_HTTP."?&ik=".$_SESSION['id_key']."&view=pr&pnl=l".$this->proxy_defeat());
$this->gmail_data = GMailer::execute_curl(
/* $this->GM_LNK_GMAIL_HTTP."?ik=".$_SESSION['id_key']."&view=up", */
$url,
/* $this->GM_LNK_GMAIL_HTTP."?view=up", */
$refer,
'post',
$postdata
);
GMailer::parse_gmail_response($this->gmail_data);
/* Debugger::say("editLabel url: ".print_r($this->GM_LNK_GMAIL_HTTP."?view=up",true)); */
/* Debugger::say("editLabel refer: ".print_r($refer,true)); */
/* Debugger::say("editLabel postdata: ".print_r($postdata,true)); */
/* Debugger::say("editLabel: ".$this->gmail_data); */
// Changed by Neerav; 28 June 2005
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "$action label",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
// Added by Neerav; 12 July 2005
$a = array(
"action" => "$action label",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Create/edit a filter.
*
* @return bool Success or not.
Extended return: array(bool,string message)
* @param integer $filter_id Filter ID to be edited, or "0" for creating a new one
* @param string $from
* @param string $to
* @param string $subject
* @param string $has
* @param string $hasnot
* @param bool $hasAttach
* @param bool $archive
* @param bool $star
* @param bool $label
* @param string $label_name
* @param bool $forward
* @param string $forwardto
* @param bool $trash
* @author Neerav
* @since 25 Jun 2005
*/
function editFilter($filter_id, $from, $to, $subject, $has, $hasnot, $hasAttach,
$archive, $star, $label, $label_name, $forward, $forwardto, $trash, $applyfilternow = false, $test_filter = false) {
if ($test_filter) {
$action = "test";
} elseif ($filter_id == 0) {
$action = "create";
} else {
$action = "edit";
}
if ($this->isConnected()) {
$query = "";
if ($action != "test") {
$query .= "view=pr";
$query .= "&pnl=f";
$query .= "&at=".$this->at_value();
}
if ($action == "create") {
// create new filter
$query .= "&act=cf";
$query .= "&cf_t=cf";
} elseif ($action == "test") {
$query .= "&search=cf";
$query .= "&view=tl";
$query .= "&start=0";
$query .= "&cf_f=cf1";
$query .= "&cf_t=cf2";
} else {
// edit existing filter
$query .= "&act=rf";
$query .= "&cf_t=rf";
}
$query .= "&cf1_from=" . urlencode($from);
$query .= "&cf1_to=" . urlencode($to);
$query .= "&cf1_subj=" . urlencode($subject);
$query .= "&cf1_has=" . urlencode($has);
$query .= "&cf1_hasnot=". urlencode($hasnot);
$query .= "&cf1_attach="; $query .= ($hasAttach == true) ? "true" : "false" ;
$query .= "&cf2_ar=" ; $query .= ($archive == true) ? "true" : "false" ;
$query .= "&cf2_st=" ; $query .= ($star == true) ? "true" : "false" ;
$query .= "&cf2_cat=" ; $query .= ($label == true) ? "true" : "false" ;
$query .= "&cf2_sel=" . urlencode($label_name);
/* if ($action == "test") { */
/* $query .= "&cf2_emc=" ; $query .= ($forward == true) ? "true" : "" ; */
/* } else { */
$query .= "&cf2_emc=" ; $query .= ($forward == true) ? "true" : "" ;
/* } */
if ($action == "test") {
$query .= "&cf2_email=" ; $query .= urlencode($forwardto);
} else {
$query .= "&cf2_email=" ; $query .= ($forwardto=="") ? 'email%20address': urlencode($forwardto);
}
$query .= "&cf2_tr=" ; $query .= ($trash == true) ? "true" : "false" ;
// in edit, maybe also create? not in test.
//&th=10d16a8192667aa2&ww=1015&qt=&prf=1&rq=xm&
if ($action == "edit" or ($action == "test" and $filter_id > 0)) {
$query .= "&ofid=".$filter_id;
}
$refer = "";
if ($action == "test") {
// no referrer for test
$query .= $this->proxy_defeat("nodash"); // to fool proxy
} else {
// apply the filter to matched conversations; Added by Neerav; 28 Aug 2006
$query .= "&irf=" ; $query .= ($applyfilternow == true) ? "true" : "false" ;
// create referer
$refer .= "&pnl=f";
$refer .= "&search=cf";
$refer .= "&view=tl";
$refer .= "&start=0";
$refer .= "&cf_f=cf1";
$refer .= "&cf_t=cf2";
$refer .= "&cf1_from=" . urlencode($from);
$refer .= "&cf1_to=" . urlencode($to);
$refer .= "&cf1_subj=" . urlencode($subject);
$refer .= "&cf1_has=" . urlencode($has);
$refer .= "&cf1_hasnot=". urlencode($hasnot);
$refer .= "&cf1_attach="; $refer .= ($hasAttach == true) ? "true" : "false" ;
if ($action == "edit") {
$refer .= "&cf2_ar=" ; $refer .= ($archive == true) ? "true" : "false" ;
$refer .= "&cf2_st=" ; $refer .= ($star == true) ? "true" : "false" ;
$refer .= "&cf2_cat=" ; $refer .= ($label == true) ? "true" : "false" ;
$refer .= "&cf2_sel=" . urlencode($label_name);
$refer .= "&cf2_emc=" ; $refer .= ($forward == true) ? "true" : "" ;
$refer .= "&cf2_email=" . urlencode($forwardto);
$refer .= "&cf2_tr=" ; $refer .= ($trash == true) ? "true" : "false" ;
$refer .= "&ofid=" . urlencode($filter_id);
}
$refer .= $this->proxy_defeat(); // to fool proxy
$query .= $this->proxy_defeat("nodash"); // to fool proxy
}
/* Debugger::say("<br />\n$query\n$refer\n"); */
/* */
/* exit; */
/* */
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
(($refer !== "") ? $this->GM_LNK_GMAIL."?".$refer : ""),
'get'
);
GMailer::parse_gmail_response($this->gmail_data);
/* Debugger::say(print_r($this->gmail_data,true)); */
/* Debugger::say(print_r($this->raw,true)); */
/* exit; */
//$updated_snapshot = new GMailSnapshot(GM_PREFERENCE, $this->raw, $this->use_session);
if ($action == "test") {
$status = (isset($this->raw["ts"])/* and isset($this->raw["t"]) */) ? 1 : 0; // removed second test to prevent error when there are no matching results; changed by Neerav; 12 May 2007
$message = (isset($this->raw["ts"][5])) ? $this->raw["ts"][5] : "";
} else {
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
}
$a = array(
"action" => "$action filter",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "$action filter",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Retrieve a web clipping
*
* @author Neerav
* @since 22 April 2006
*/
function webClip($action = "get", $thread_id = 0, $mailbox = "") {
if ($this->isConnected()) {
$query = "";
$update_cookie = false;
if ($action == "get") {
$query .= "&view=fb";
} elseif ($action == "thread") {
//$query .= "&ik=".$ik.value.here;
$query .= "&view=ad";
$query .= (($thread_id) ? "&th=".$thread_id : "");
$query .= "&mg=".urlencode("3,2"); //what is this junk? &mg=3,2,2,2,2,2,2,2,3,4,3,4
if ($mailbox === 0 or $mailbox == "") $mailbox = "inbox";
if (in_array(strtolower($mailbox),$this->gmail_reserved_names)) {
$query .= "&search=".urlencode($mailbox);
} else {
$query .= "&search=cat&cat=".urlencode($mailbox);
}
$query .= "&qt=";
$query .= "&act=rd";
$query .= (($thread_id) ? "&t=".$thread_id : "");
$query .= "&at=".$this->at_value();
} elseif ($action == "off" or $action == "on") {
// turn webclips on/off; Added by Neerav; 13 May 2006
//$query .= "&ik=".$ik.value.here;
$query .= "&view=up";
$query .= "&act=co_".(($action == "off") ? 0 : 1);
$query .= "&at=".$this->at_value();
$query .= "&rq=xm";
$query .= $this->proxy_defeat("nodash");
$update_cookie = true;
} else {
$a = array(
"action" => "web clip: ".$action,
"status" => "failed",
"message" => "invalid action"
);
array_unshift($this->return_status, $a);
return array();
}
$query .= $this->proxy_defeat();
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
"",
'get',
$query, "","", $update_cookie
);
GMailer::parse_gmail_response($this->gmail_data,true);
//Debugger::say("web clip response: ".print_r($this->gmail_data,true));
//Debugger::say("web clip response raw: ".print_r($this->raw,true));
if ($action == "get" or $action == "thread") {
GMailSnapshot::web_clip_snapshot($this->raw["1"][1][3]);
//Debugger::say("web clip response raw: ".print_r($this->raw,true));
return $this->web_clips;
} else {
//Debugger::say("web clip response: ".print_r($this->gmail_data,true));
/* $a = array( */
/* "action" => "retrieve web clip", */
/* "status" => "failed", */
/* "message" => "libgmailer: not connected" */
/* ); */
/* array_unshift($this->return_status, $a); */
return true;
}
} else {
$a = array(
"action" => "retrieve web clip",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Delete a filter.
*
* @return bool Success or not.
Extended return: array(bool success/fail, string message)
* @param string $id Filter ID to be deleted
* @author Neerav
* @since 25 Jun 2005
*/
function deleteFilter($id) {
if ($this->isConnected()) {
$query = "";
$query .= "act=df_".$id;
$query .= "&at=".$this->at_value();
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?ik=&view=up",
$this->GM_LNK_GMAIL."?pnl=f&view=pr".$this->proxy_defeat(),
'post',
$query
);
GMailer::parse_gmail_response($this->gmail_data);
//$updated_snapshot = new GMailSnapshot(GM_PREFERENCE, $this->raw, $this->use_session);
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "delete filter",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "delete filter",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Edit contact groups.
*
* @return bool Success or not.
Extended return: array(bool success/fail, string message)
* @param string $id Contact group ID to "edit" (-1 if creating a new group)
* @param string $name Contact group's name
* @param string $action Action to be performed on Contact group (rename, create, delete, remove_from, add_to)
* @param string $data Data required for Action (optional depending on the Action) -- rename = new name, for create/add_to/remove_from = string or array of contact ids or email addresses (if using remove_from and email addresses, each address should be as contact_id/hide@address.com, e.g. 9f/hide@address.com )
* @author Neerav
* @since 10 Jan 2006
* Changes to accommodate contact ids as well as email addresses based on cmcnulty
*/
function editGroup($id,$name,$action,$data = "") {
if ($this->isConnected()) {
$query = "";
if ($action == "rename") {
$refer = $this->GM_LNK_GMAIL."?search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
$query .= "&act="."rcl_".$id."^".rawurlencode($data); // $data is the new name
$query .= "&at=".$this->at_value();
$query .= "&cpt=cpta";
$query .= "&cl_id=".$id;
$query .= "&cl_nm=".rawurlencode($name); // $name is the old name
} elseif ($action == "delete") {
$refer = $this->GM_LNK_GMAIL."?view=cl&search=contacts&pnl=l".$this->proxy_defeat();
$query .= "&act=dcal";
$query .= "&at=".$this->at_value();
$query .= "&cpt=&cl_nw=&cl_id=&cl_nm=";
$query .= "&cl=".$id;
$query .= "&cl_nm=".rawurlencode($name); // $name is the old name
} elseif ($action == "create") {
$refer = $this->GM_LNK_GMAIL."?view=nctl&search=contacts".$this->proxy_defeat();
// accept contact id or email addresses based on cmcnulty; Neerav; 15 Feb 2007
$id_as_string = (is_array($data)) ? implode(", ",$data) : $data;
// as contact ids
if(strpos($id_as_string,"@") === false and !preg_match("/[^0-9a-f\,\ ]/",$id_as_string) and $id_as_string != ""){
$query .= "&cpt=cpti";
if (is_array($data)) {
$count_ids = count($data);
for ($i = 0; $i < $count_ids; $i++) {
$query .= "&c=".$data[$i]; // $query needs to be a string because of this
}
} else {
$query .= "&c=".$data;
}
// as email addresses
} else {
$query .= "&cpt=cpta";
$query .= "&ce=".rawurlencode($id_as_string);
}
$query .= "&act=ancl"; // add new contact list
$query .= "&at=".$this->at_value();
$query .= "&cl_nm=".rawurlencode($name);
//$query['ce'] = (is_array($data)) ? implode(", ",$data) : $data;
} elseif ($action == "remove_from") {
$refer = $this->GM_LNK_GMAIL."?search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
// accept contact id or email addresses based on cmcnulty; Neerav; 15 Feb 2007
$id_as_string = (is_array($data)) ? implode(", ",$data) : $data;
// as contact ids
if(strpos($id_as_string,"@") === false and !preg_match("/[^0-9a-f\,\ ]/",$id_as_string)){
$query .= "&cpt=cpti";
$query .= "&cl_nw=false";
if (is_array($data)) {
$count_ids = count($data);
for ($i = 0; $i < $count_ids; $i++) {
$query .= "&c=".$data[$i]; // $query needs to be a string because of this
}
} else {
$query .= "&c=".$data;
}
// as email addresses
} else {
$query .= "&cpt=cpta";
if (is_array($data)) {
$count_ids = count($data);
for ($i = 0; $i < $count_ids; $i++) {
$query .= "&cr="/* ."1b5%2F (/)" */.rawurlencode(str_replace("%2F","/",$data[$i])); // $query needs to be a string because of this
}
} else {
$query .= "&cr=".rawurlencode(str_replace("%2F","/",$data));
}
}
$query .= "&act=rfcl"; // remove from contact list
$query .= "&at=".$this->at_value();
$query .= "&cl_id=".$id;
$query .= "&cl_nm=".rawurlencode($name);
/* $add_count = count($data); */
/* for ($i = 0; $i < $add_count; $i++) { */
/* $query .= "&cr=".$data[$i]['id']."/".$data[$i]['email']; */
/* } */
} elseif ($action == "add_to") {
$refer = $this->GM_LNK_GMAIL."?&search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
// accept contact id or email addresses based on cmcnulty; Neerav; 15 Feb 2007
$id_as_string = (is_array($data)) ? implode(", ",$data) : $data;
// as contact ids
if(strpos($id_as_string,"@") === false and !preg_match("/[^0-9a-f\,\ ]/",$id_as_string)){
$query .= "&cpt=cpti";
$query .= "&cl_nw=false";
if (is_array($data)) {
$count_ids = count($data);
for ($i = 0; $i < $count_ids; $i++) {
$query .= "&c=".$data[$i]; // $query needs to be a string because of this
}
} else {
$query .= "&c=".$data;
}
} else {
// as email addresses
$query .= "&cpt=cpta";
$query .= "&ce=".rawurlencode($id_as_string);
}
$query .= "&act=atcl"; // add to contact list
$query .= "&at=".$this->at_value();
$query .= "&cl_id=".$id;
$query .= "&cl_nm=".rawurlencode($name);
} else {
$a = array(
"action" => $action." contact group",
"status" => "failed",
"message" => "editGroup(): invalid ACTION"
);
array_unshift($this->return_status, $a);
return false;
}
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?ik=&view=up",
$refer,
'post',
$query
);
GMailer::parse_gmail_response($this->gmail_data);
$orig_group_id = $id;
if ($orig_group_id == -1 and $this->raw["ar"][1]) {
if (isset($this->raw["clv"][1][1])) $id = $this->raw["clv"][1][1];
}
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => $action." contact group",
"status" => (($status) ? "success" : "failed"),
"message" => $message,
"contact_id" => "$id"
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => $action." contact group",
"status" => "failed",
"message" => "libgmailer: not connected",
"contact_id" => "$id"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Set general, forwarding and POP settings of Gmail account.
*
* @return bool Success or not.
Extended return: array(bool status, string message)
* @param bool $use_outgoing_name Use outgoing name (instead of the default)?
* @param string $outgoing_name Outgoing name
* @param bool $use_reply_email Use replying email address (instead of the default)?
* @param string $reply_to Replying email address
* @param string $language Language
* @param int $page_length Page length: either 25, 50 or 100
* @param bool $shortcut Enable keyboard shortcut?
* @param bool $indicator Enable personal level indicator?
* @param bool $snippet Enable snippet?
* @param bool $custom_signature Enable custom signature?
* @param string $signature Custom signature
* @param bool $utf_encode Use utf-8 encoding?
* @param bool $use_forwarding Forward all incoming messages?
* @param string $forward_to Forward to this email address
* @param string $forward_action What to do with forwarded message? (selected, archive, trash)
* @param int $use_pop Enable POP access? {0 = disabled, 1 = enabled, 2 = from now, 3 = all}
* @param int $pop_action What to do with forwarded message? {0 = keep, 1 = archive, 2 = trash}
* @param bool $rich_text Use rich text formatting?
* @param bool $expand_label_box Expand label box
* @param bool $expand_invite_box Expand invite box
* @param bool $vacation_on Vacation responder - ON/OFF
* @param string $vacation_subject Vacation responder - Subject
* @param string $vacation_message Vacation responder - Message
* @param bool $vacation_contacts_only Vacation responder - Send vacation message only to those in Contacts list?
* @param bool $expand_talk_box Expand Quick Contacts box
* @param bool $chat_archive Save chat sessions
* @param int $chat_box_length Number of contacts displayed in Quick Contacts list
* @param bool $chat_box_placement Placement of Quick Contacts box {0 = above Labels, 1 = below Labels}
* @param bool $chat_autoadd Auto/manual addition of contacts to Quick Contacts {0 = manual, 1 = auto}
* @param bool $chat_sound Play sound when new chat message arrives
* @param bool $my_pict_visible My Picture visibility {0 = all Gmail users, 1 = only people can chat with}
* @param bool $contact_pict_visible Visibility of Contacts' Pictures {0 = show all, 1 = show only what I chose}
* @author Neerav
* @since 29 Jun 2005
* @updated 13 Sep 2006
*/
function setSetting(
$language, $page_length, $shortcut, $indicator, $snippet, $custom_signature,
$signature, $msg_encoding,
$use_forwarding, $forward_to, $forward_action,
$use_pop, $pop_action, $rich_text,
$expand_label_box = 1, $expand_invite_box = 1,
$vacation_on = 0, $vacation_subject = "", $vacation_message = "", $vacation_contacts_only = 0,
$expand_talk_box = 1, $chat_archive = 0, $chat_box_length = 10, $chat_box_placement = 0, $chat_autoadd = 0, $chat_sound = 0,
$my_pict_visible = 1, $contact_pict_visible = 0
) {
/*
end vacation NOW:
GET http://mail.google.com/mail/?&ik=xxxxxxx&search=inbox&view=tl&start=0&act=prefs&at=xxxx-xxxx&p_bx_ve=0&zx=ferur3mmq41e HTTP/1.1
Referer: http://mail.google.com/mail/?&ik=xxxxxxx&view=pr&pnl=g&zx=xorfqampe0ml
// general
"bx_hs" // (boolean) keyboard shortcuts {0 = off, 1 = on}
"bx_show0" // (boolean) labels box {0 = collapsed, 1 = expanded}
"ix_nt" // (integer) msgs per page (maximum page size)
"sx_dl" // (string) display language (en = English, en-GB = British-english, etc)
"bx_sc" // (boolean) personal level indicators {0 = no indicators, 1 = show indicators}
"bx_show1" // (boolean) invite box {0 = collapsed, 1 = expanded}
"sx_sg" // (string) signature
"bx_ns" // (boolean) no snippets {0 = show snippets, 1 = no snippets}
"bx_cm" // (boolean) rich text composition {0 = plain text, 1 = rich text}
"bx_en" // (boolean) outgoing message encoding {0 = default, 1 = utf-8}
"bx_ve" // (boolean) vacation message enabled {0 = OFF, 1 = ON}
"sx_vs" // (string) vacation message subject
"sx_vm" // (string) vacation message text
"bx_vc" // SPECIAL CASE (string to boolean) vacation message, send only to contacts list
"bx_show3" // (boolean) gtalk box {0 = collapsed, 1 = expanded}
"ix_pp" // (boolean) My Picture visibility {0 = all Gmail users, 1 = only people can chat with}
"bx_pd" // (boolean) Visibility of Contacts' Pictures {0 = show all, 1 = show only what I chose}
// forwarding and pop
"sx_em" // (string) forward to email address
"sx_at" // (string) action after forwarding {selected, archive, trash} (selected means "keep")
"bx_pe" // (integer) pop enabled {0 = disabled, 1 = already enabled, 2 = from now, 3 = all}
"ix_pd" // (integer) action after pop access {0 = keep, 1 = archive, 2 = trash}
// mobile
"sx_pf" // (string) list of mailboxes to display in Gmail Mobile
// other
"bx_cm" // (boolean) rich text composition {0 = plain text, 1 = rich text}
// Chat
"ix_ca" // (boolean) save chat archives? {0 = off, 1 = on}
"ix_ql" // (integer) Quick [contacts] List [length]
"bx_lq" // (boolean) Location [of] Quick [contacts list] {0 = above labels, 1 = below labels}
"bx_aa" // (boolean) Auto Add suggested contacts
"bx_sn" // (boolean) Sounds {0 = off, 1 = on}
// deprecated
//"sx_dn" // (string) display name
//"sx_rt" // (string) reply to email address
*/
if ($this->isConnected()) {
$post_fields = array();
$post_url = "";
$query = "";
//$query .= "&ik=".IKVALUE;
$post_url .= "&view=up";
$post_fields['act'] = "prefs";
$post_url .= "&act=prefs";
$post_fields['at'] = $this->at_value();
$post_url .= "&at=".$this->at_value();
$post_fields['search'] = "";
/* $query .= "&sx_dl=" . $language; */
/* $query .= "&ix_nt=" . $page_length; */
/* $query .= "&bx_hs="; $query .= ($shortcut) ? "1" : "0" ; */
/* $query .= "&bx_sc="; $query .= ($indicator) ? "1" : "0" ; */
/* $query .= "&bx_ns="; $query .= ($snippet) ? "0" : "1" ; // REVERSED because we originally reversed it for convenience */
/* $query .= "&sx_sg="; $query .= $custom_signature; */
/* $query .= "&sx_sg="; $query .= ($custom_signature) ? urlencode($signature) : urlencode("\n\r") ; */
/* $query .= "&bx_ve="; $query .= ($vacation_on) ? "1" : "0" ; */
/* $query .= "&sx_vs="; $query .= urlencode($vacation_subject) ; */
/* $query .= "&sx_vm="; $query .= urlencode($vacation_message) ; */
/* $query .= "&bx_en="; $query .= ($msg_encoding) ? "1" : "0" ; */
/* $query .= "&ix_ca="; $query .= ($chat_archive) ? "1" : "0" ; */
/* $query .= "&ix_ql="; $query .= (is_numeric($chat_box_length) and $chat_box_length > 0) ? $chat_box_length : "10" ; */
/* $query .= "&bx_lq="; $query .= ($chat_box_placement) ? "1" : "0" ; */
/* $query .= "&bx_aa="; $query .= ($chat_autoadd) ? "1" : "0" ; */
/* $query .= "&bx_sn="; $query .= ($chat_sound) ? "1" : "0" ; */
/* $query .= "&ix_pp"; $query .= ($my_pict_visible) ? "1" : "0" ; */
/* $query .= "&bx_pd"; $query .= ($contact_pict_visible) ? "1" : "0" ; */
/* $query .= "&bx_en"; $query .= ($msg_encoding) ? "1" : "0" ; */
/* $post_fields['sx_dl'] = $language; */
/* $post_fields['ix_nt'] = $page_length; */
/* $post_fields['bx_hs'] = ($shortcut) ? "1" : "0" ; */
/* $post_fields['bx_sc'] = ($indicator) ? "1" : "0" ; */
/* $post_fields['bx_ns'] = ($snippet) ? "0" : "1" ; // REVERSED because we originally reversed it for convenience */
/* $post_fields['sx_sg'] = $custom_signature; */
/* $post_fields['sx_sg'] = ($custom_signature) ? urlencode($signature) : urlencode("\n\r") ; */
/* $post_fields['bx_ve'] = ($vacation_on) ? "1" : "0" ; */
/* $post_fields['sx_vs'] = urlencode($vacation_subject) ; */
/* $post_fields['sx_vm'] = urlencode($vacation_message) ; */
/* $post_fields['bx_en'] = ($msg_encoding) ? "1" : "0" ; */
/* $post_fields['ix_ca'] = ($chat_archive) ? "1" : "0" ; */
/* $post_fields['ix_ql'] = (is_numeric($chat_box_length) and $chat_box_length > 0) ? $chat_box_length : "10" ; */
/* $post_fields['bx_lq'] = ($chat_box_placement) ? "1" : "0" ; */
/* $post_fields['bx_aa'] = ($chat_autoadd) ? "1" : "0" ; */
/* $post_fields['bx_sn'] = ($chat_sound) ? "1" : "0" ; */
/* $post_fields['ix_pp'] = ($my_pict_visible) ? "1" : "0" ; */
/* $post_fields['bx_pd'] = ($contact_pict_visible) ? "1" : "0" ; */
/* $post_fields['bx_en'] = ($msg_encoding) ? "1" : "0" ; */
$post_fields['p_bx_hs'] = ($shortcut) ? "1" : "0" ;
$post_fields['p_bx_show0'] = ($expand_label_box) ? "1" : "0" ;
$post_fields['p_ix_nt'] = $page_length;
$post_fields['p_bx_pe'] = ($use_pop >= 0 and $use_pop <= 3) ? $use_pop : "0" ;
$post_fields['p_bx_show1'] = ($expand_invite_box) ? "1" : "0" ;
$post_fields['p_bx_ve'] = ($vacation_on) ? "1" : "0" ;
$post_fields['p_bx_cm'] = ($rich_text) ? "1" : "0" ;
$post_fields['p_bx_en'] = ($msg_encoding) ? "1" : "0" ;
$post_fields['p_ix_pd'] = ($pop_action >= 0 and $pop_action <= 2) ? $pop_action : "0" ;
/* $post_fields['p_ix_fv'] = "true"; */
$post_fields['p_bx_show3'] = ($expand_talk_box) ? "1" : "0" ;
$post_fields['p_sx_vm'] = $vacation_message;
$post_fields['p_sx_sg'] = ($custom_signature) ? $signature : "\n\r" ;
$post_fields['p_sx_dl'] = $language;
$post_fields['p_bx_sc'] = ($indicator) ? "1" : "0" ;
$post_fields['p_sx_vs'] = $vacation_subject ;
$post_fields['p_bx_ns'] = ($snippet) ? "0" : "1" ; // REVERSED because we originally reversed it for convenience
$post_fields['p_sx_em'] = ($use_forwarding) ? $forward_to : "" ;
$post_fields['p_ix_ca'] = ($chat_archive) ? "1" : "0" ;
$post_fields['p_bx_aa'] = ($chat_autoadd) ? "1" : "0" ;
$post_fields['p_ix_ql'] = (is_numeric($chat_box_length) and $chat_box_length > 0) ? $chat_box_length : "10" ;
$post_fields['p_bx_lq'] = ($chat_box_placement) ? "1" : "0" ;
$post_fields['p_bx_sn'] = ($chat_sound) ? "1" : "0" ;
$post_fields['p_ix_pp'] = ($my_pict_visible) ? "1" : "0" ;
$post_fields['p_bx_pd'] = ($contact_pict_visible) ? "1" : "0" ;
$post_fields['p_sx_at'] = (( $forward_action == "selected"
or $forward_action == "archive"
or $forward_action == "trash"
) ? $forward_action : "selected"
);
// vacation responder; by Neerav; 21 Dec 2005
// includes p_sx_vm p_sx_vs and p_bx_ve
if ($vacation_contacts_only) {
$post_fields['p_bx_vc'] = "true";
$post_fields['bx_vc'] = "on";
//$query .= "&bx_vc=on";
} else {
$post_fields['dp'] = "bx_vc";
$post_fields['bx_vc'] = ""; // empty
//$query .= "&bx_vc="; // empty
}
//$post_fields['p_bx_aa'] = $aa_unknown;
//http://mail.google.com/mail/?&ik=xxxxx&view=up&act=prefs&at=xxxx-xxxx
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$post_url,
$this->GM_LNK_GMAIL."?&view=pr&pnl=g".$this->proxy_defeat(),
'post',
$post_fields
);
GMailer::parse_gmail_response($this->gmail_data);
// get updated cookie
ereg("S=gmail=([^\:]*):gmail_yj=([^\:]*):gmproxy=([^\;]*);",$this->gmail_data,$matches);
$this->cookie_str = ereg_replace(
"S=gmail=([^\:]*):gmail_yj=([^\:]*):gmproxy=([^\;]*);",
"S=gmail=".$matches[1].":gmail_yj=".$matches[2].":gmproxy=".$matches[3].";",
$this->cookie_str
);
// save updated cookie
GMailer::saveSessionToBrowser();
$status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0;
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "set settings",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "set settings",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
function execute_curl($url, $referrer, $method, $post_data = "", $extra_type = "", $extra_data = "", $update_cookie = true, $follow = true) {
$message = '';
if ($method != "get" and $method != "post") {
$message = 'The cURL method is invalid.';
}
if ($url == "") {
$message = 'The cURL url is blank.';
}
// error
if ($message != '') {
array_unshift($this->return_status, array("action" => "execute cURL", "status" => "failed", "message" => $message));
return;
}
$manual_followlocation = false;
/* set_time_limit(150); */
$c = curl_init();
if ($method == "get") {
curl_setopt($c, CURLOPT_URL, $url);
if ($referrer != "") {
curl_setopt($c, CURLOPT_REFERER, $referrer);
}
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
/* //if ($follow) { */
/* // $manual_followlocation = true; */
/* //} */
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
if ($extra_type != "noheader") {
curl_setopt($c, CURLOPT_HEADER, 1);
}
if ($extra_type != "nocookie") {
curl_setopt($c, CURLOPT_COOKIE, (($extra_type == "cookie") ? $extra_data : $this->cookie_str));
}
} elseif ($method == "post") {
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, $post_data);
if ($referrer != "") {
curl_setopt($c, CURLOPT_REFERER, $referrer);
}
$this->CURL_PROXY(&$c);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
/* //if ($extra_type == "nocookie" or !$follow) { */
/* // // already false */
/* //} else { */
/* // $manual_followlocation = true; */
/* //} */
curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT);
curl_setopt($c, CURLOPT_HEADER, 1);
if ($extra_type != "nocookie") {
curl_setopt($c, CURLOPT_COOKIE, (($extra_type == "cookie") ? $extra_data : $this->cookie_str));
}
}
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($c, CURLOPT_TIMEOUT, 25);
// debugging cURL
if (GM_DEBUG_CURL) {
$fd = fopen("debug_curl.txt", "a+");
curl_setopt($c, CURLOPT_VERBOSE, 1);
curl_setopt($c, CURLOPT_STDERR, $fd);
}
$gmail_response = curl_exec($c);
curl_close($c);
// close debugging file
if (GM_DEBUG_CURL and isset($fd)) {
@fclose($fd);
Debugger::say("Gmail response: ".print_r($gmail_response,true),"debug_curl.txt");
}
if ($update_cookie) GMailer::update_cookies($gmail_response);
return $gmail_response;
}
/**
* Update Gmail cookie
*
* @return bool true
* @param string raw HTML header
* @access private
* @static
* @author Neerav
* @since 19 Apr 2006
*/
function update_cookies ($data = "") {
// completely rewritten (expanded, fixed); Neerav; 25 Jan 2007
$new_cookies = GMailer::get_cookies($data);
$parse_headers = (($data == "") ? $this->gmail_data : $data);
$replace_cookies = array("S","GX","GXAS_SEC","GMAIL_AT","GMAIL_HELP");
//Debugger::say("new cookies: ".print_r($new_cookies,true));
//Debugger::say("old cookie: ".print_r($this->cookie_str,true));
//Debugger::say("set new cookies: ".print_r($parse_headers,true));
foreach($replace_cookies as $indexval => $cookie) {
$matches = array();
if (preg_match("/".$cookie."=([^;]*);/U", $parse_headers, $matches)) {
//Debugger::say("cookie matches: ".print_r($matches,true));
if (preg_match("/".$cookie."=([^;]*);/U", $this->cookie_str)) {
$this->cookie_str = preg_replace("/".$cookie."=([^;]*);/U", $cookie."=".$matches[1].";", $this->cookie_str);
} else {
$this->cookie_str = $cookie."=".$matches[1]."; ".$this->cookie_str;
}
}
}
// save updated cookie
GMailer::saveSessionToBrowser();
//Debugger::say("new cookie: ".print_r($this->cookie_str,true));
return true;
}
/**
* Set Mobile settings of Gmail account.
*
* @return bool Success or not.
Extended return: array(bool status, string empty message)
* @param array $mobile_display Array of standard boxes and labels to "display"
* @author Neerav
* @since 23 Dec 2005
*/
function setMobileSetting($mobile_display) {
if ($this->isConnected()) {
/* if ($this->domain !== "") { */
/* $a = array( */
/* "action" => "set mobile settings", */
/* "status" => "failed", */
/* "message" => "this feature not available yet for hosted domains. Check for libgmailer updates." */
/* ); */
/* array_unshift($this->return_status, $a); */
/* return false; */
/* } */
// should be POST, but we are faking it with a GET encoded POST
//$post = array();
//$post['nvp_bu_done'] = "Save";
$get = "";
$post_url = str_replace("&zx=", "", $this->proxy_defeat("nodash"))."-/?a=cfa";
$post_url .= "&at=".$this->at_value();
$count_mob_display = count($mobile_display);
for ($i = 0; $i < $count_mob_display; $i++) {
if (isset($mobile_display[$i]) and $mobile_display[$i] != "") {
$get .= "&cfvc_".$i."=".rawurlencode($mobile_display[$i]);
}
}
$get .= "&nvp_bu_done=Save";
$url = $this->GM_LNK_GMAIL_MOBILE.$post_url;
/* */
/* $this->gmail_data = GMailer::execute_curl( */
/* "http://mail.google.com/a/".$this->domain."/?ui=mobile&zy=j", */
/* "", */
/* 'get', "" */
/* ); */
/* Debugger::say("test setMobile A: ".print_r($this->gmail_data,true)); */
/* */
/* exit; */
/* Debugger::say("post: ".print_r($get,true)); */
/* Debugger::say("post url: ".print_r($url,true)); */
/* Debugger::say("post data: ".print_r($get,true)); */
/* Debugger::say("post referrer: ".print_r($this->GM_LNK_GMAIL_MOBILE.str_replace("&zx=", "", $this->proxy_defeat("nodash"))."-/?v=cmf",true)); */
/* Debugger::say("post cookie: ".print_r($this->cookie_str,true)); */
/* Debugger::say("cookie needed: ".print_r("Cookie: PREF=ID=e850c57148d6143b:TM=1160652008:LM=1166333423:GM=1:S=lI-8ULtrRIq0NejV; rememberme=true; __utmz=173272373.1162274748.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none); __utma=173272373.360229672.1162274748.1173849011.1173893867.8; SID=DQAAAIsAAABbtiSSFhhuA7_oQEqACrgUf5wLM1o-QOi9o7Kftt5Pdswwasc9W-LN6U0tROaA-GR1fclQOxLm_iJjNxwY0r0EvYLXzkD3wYhIFsHR8_8SYYBnGoBiqm6yJyYB0lSu4h18G5RHsrD0Dm9kH7CYlEMy_K2CQmyt2nrTQG57tb4rCz0sHZu-fd-nK9eDOAFPk8g; S=gmail=oSldHvjJpu1SivgKNjIUgw:gmail_yj=vH0eUECIEzF9rE6qWXScTg:gmproxy=jbp9JfHGs7s:gmproxy_yj=6G2Rh5ySmf8:gmproxy_yj_sub=eU4Eyy3kwAo; GMAIL_AT=c81d5736a9dbde98-1114ed93539; __utmc=173272373; __utmb=173272373; GXAS=modi.tk=DQAAAHEAAAAKFD-_XtIqZGvFWHUX0fvewLLoFs22zaUhKI_tf2T3zbWy6HeZ5hFPyaxFkct3OqP4xvXRybPRix85kCkry1Wa6pF4BVIc7cvDP9bMmr_a5jno8BoXYahrulA5SoJ8RqX9ZQ2jadin_O62SnFwul6I9Sr-N7Z4gksS75c3mPPBVg; GMAIL_HELP=hosted:1; S=gmail=oV_9aSkAbfIlpsgi_TEXRQ:gmail_yj=vH0eUECIEzF9rE6qWXScTg:gmproxy=jbp9JfHGs7s:gmproxy_yj=6G2Rh5ySmf8:gmproxy_yj_sub=eU4Eyy3kwAo:dasher_cpanel=xmb7gqo9PtE; TZ=-330",true)); */
if ($this->domain !== "") {
$temp_cookie = str_replace("GXAS_SEC=","GXAS=",$this->cookie_str);
//$temp_cookie = str_replace(" S=;","",$this->cookie_str);
$this->gmail_data = GMailer::execute_curl(
$url,
$this->GM_LNK_GMAIL_MOBILE.str_replace("&zx=", "", $this->proxy_defeat("nodash"))."-/?v=cmf",
'post',
$get,
"cookie", $temp_cookie
);
} else {
$this->gmail_data = GMailer::execute_curl(
$url,
$this->GM_LNK_GMAIL_MOBILE.str_replace("&zx=", "", $this->proxy_defeat("nodash"))."-/?v=cmf",
'post',
$get
);
}
// Gmail changed <a href="?v=cmf"> to <a href=<a id="bnm" href="?v=cmf">; Neerav; 6 Jan 2007
//$status = (strstr($this->gmail_data,'<a href="?v=cmf">more views</a>') === false) ? 0 : 1;
$status = (strstr($this->gmail_data,' href="?v=cmf">') === false) ? 0 : 1;
$a = array(
"action" => "set mobile settings",
"status" => (($status) ? "success" : "failed"),
"message" => ""
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "set mobile settings",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Change Gmail Language
*
* @return bool Success or not.
* @param string $old_lang Current language
* @param string $new_lang New language
* @author Neerav
* @since 27 Nov 2005
*/
function changeLanguage($new_lang, $old_lang = "") {
if ($this->isConnected()) {
$query = "";
$refer = "";
//$query .= "&ik=".IKVALUE;
$query .= "&view=lpc&gfl=".(($old_lang != "")? $old_lang:"en").">l=".$new_lang;
//$refer .= "&ik=".IKVALUE;
$refer .= "&view=pr&pnl=g";
$refer .= $this->proxy_defeat(); // to fool proxy
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$query,
$this->GM_LNK_GMAIL."?".$refer,
'get'
);
GMailer::update_cookies();
// GMAIL DOES NOT RESPOND WITH A STATUS MESSAGE
$a = array(
"action" => "change language",
"status" => "success",
"message" => "(no message)"
);
array_unshift($this->return_status, $a);
return true;
} else {
$a = array(
"action" => "change language",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Personalities / Custom FROM addresses
*
* @return bool Success or not.
* @param string $action An action to perform: [set this address to] default, delete, reply_sent, reply_default, edit, edit_google, send_verify, verify_code
* @param string $email
* @param string $name
* @param string $reply_to
* @param integer $code Verification code for an added custom from address
* @desc Custom From Address features
* @author Neerav
* @since 25 Feb 2006
*/
function customFrom($action, $email, $name = "", $reply_to = "", $code = "") {
if ($this->isConnected()) {
$url = "&ik=&view=up";
$refer = "&view=pr&pnl=g".$this->proxy_defeat();
$method = 'post';
switch($action) {
case "default": // set this as default From email address
$postdata = "act=mcf_".urlencode($email);
$postdata .= "&at=".$this->at_value();
break;
case "delete": // remove this From email address
$postdata = "act=dcf_".urlencode($email);
$postdata .= "&at=".$this->at_value();
break;
case "reply_sent": // set reply address to that which the message was sent to
$postdata = "act=crf_1";
$postdata .= "&at=".$this->at_value();
$postdata .= "&search=";
break;
case "reply_default": // set reply address to the default From
$postdata = "act=crf_0";
$postdata .= "&at=".$this->at_value();
$postdata .= "&search=";
break;
case "edit": // update the details of an existing From address
$postdata = "cfrp=1&cfe=1&cfn=".urlencode($name)."&cfrt=".urlencode($reply_to);
$url = "&view=cf&cfe=true&cfa=".urlencode($email).$this->proxy_defeat();
$refer = $url;
break;
case "edit_google": // update the details of the Google Account info
$postdata['cfrp'] = 1;
$postdata['cfe'] = 1;
$postdata['cfgnr'] = (($name != "")?1:0);
$postdata['cfgn'] = $name;
$postdata['cfrt'] = $reply_to;
$url = "&view=cf&cfe=true&cfa=".urlencode($email).$this->proxy_defeat();
$refer = $url;
break;
/* case "add_pre": // Gmail's preparation step for adding a new From. Not required. Directly use "send_verify" */
/* $postdata = ""; */
/* $url = "&view=cf".$this->proxy_defeat(); */
/* $method = 'get'; */
/* break; */
/* case "add": // Gmail's first step in adding a new From. Not required. Directly use "send_verify" */
/* $postdata = array(); */
/* $postdata['cfrp'] = 1; */
/* $postdata['cfn'] = $name; */
/* $postdata['cfa'] = $email; */
/* $postdata['cfrt'] = $reply_to; */
/* $url = "&view=cf"; */
/* $refer = $url; */
/* break; */
case "send_verify": // send the verification email to the From address
// also used to directly add a new From address
$postdata = array();
$postdata['cfrp'] = 2;
$postdata['cfn'] = $name;
$postdata['cfa'] = $email;
$postdata['cfrt'] = $reply_to;
$postdata['submit'] = "Send Verification";
$url = "&view=cf";
$refer = $url;
break;
case "verify_code": // enter verification code to verify previously added From address
$postdata = array();
$postdata['cfrp'] = 3;
$postdata['cfrs'] = "false";
$postdata['cfn'] = $name;
$postdata['cfa'] = $email;
$postdata['cfrt'] = $reply_to;
$postdata['cfvc'] = $code;
$url = "&view=cf";
$refer = $url;
break;
default:
array_unshift(
$this->return_status,
array("action" => "custom from: $action",
"status" => "failed",
"message" => "libgmailer: Invalid action"
)
);
return 0;
}
$this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?".$url,
$this->GM_LNK_GMAIL."?".$refer,
$method,
$postdata
);
GMailer::parse_gmail_response($this->gmail_data);
if ($action == "send_verify" or $action == "add" or $action == "add_pre" or $action == "verify_code") {
$status = 1;
} else {
$status = (isset($this->raw["cfs"])) ? 1 : 0;
}
/* $status = (isset($this->raw["ar"][1])) ? $this->raw["ar"][1] : 0; */
$message = (isset($this->raw["ar"][2])) ? $this->raw["ar"][2] : "";
$a = array(
"action" => "custom from: $action",
"status" => (($status) ? "success" : "failed"),
"message" => $message
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => "custom from",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Export Contacts List
*
* @access public
* @static
* @return bool
* @param string $format
* @author (damien DOT flament AT smoofy DOT org)
* @since 1 Feb 2007
* THIS METHOD IS EXPERIMENTAL AND HAS NOT BEEN TESTED
*/
function exportContacts($format) {
if ($this->isConnected() == true) {
$postdata["at"] = $this->at_value();
if ($format == 'outlook') {
$postdata["ecf"] = 'o';
} else {
$postdata["ecf"] = 'g';
}
$postdata["ac"] = 'Export Contacts';
$this->gmail_data = $this->gmail_data = GMailer::execute_curl(
$this->GM_LNK_GMAIL."?view=fec",
$this->GM_LNK_GMAIL."?view=sec",
'post',
$postdata,
"noheader"
);
$a = array(
"action" => "export contacts",
//"status" => ($status ? "success" : "failed"),
"status" => "success",
"message" => "Contacts exported",
"contacts" => $this->gmail_data
);
array_unshift($this->return_status, $a);
return true;
} else {
$a = array(
"action" => "export contacts",
"status" => "failed",
"message" => "libgmailer: not connected"
);
array_unshift($this->return_status, $a);
return false;
}
}
/**
* Extract the AT value.
*
* @access private
* @static
* @return string
* @author Neerav
* @since 27 Nov 2005
*/
function at_value() {
$at_value = "";
$cc = split(";", $this->cookie_str);
foreach ($cc as $cc_part) {
$cc_parts = split("=", $cc_part);
if (trim($cc_parts[0]) == "GMAIL_AT") {
$at_value = $cc_parts[1];
break;
}
}
return $at_value;
}
/**
* Parse Gmail responses.
*
* @access private
* @static
* @return bool
* @param string $raw_html
* @since 7 Jun 2005
*/
function parse_gmail_response($raw_html,$non_standard = false) {
$raw_html = str_replace("\n", "", $raw_html);
$raw_html = str_replace("D([", "\nD([", $raw_html);
$raw_html = str_replace("]);", "]);\n", $raw_html);
// Fix Gmail's conversion of = and /; by Neerav; 18 Dec 2005
// Added < and >; by Neerav; 4 Mar 2007
$raw_html = str_replace(array('u003d','u002f','u003c','u003e'),array('=','/','<','>'),$raw_html);
$regexp = (!$non_standard) ? "|D\(\[(.*)\]\);|U" : "/\[(.*)\]/";
$matches = "";
preg_match_all($regexp, $raw_html, $matches, PREG_SET_ORDER);
$packets = array();
for ($i = 0; $i < count($matches); $i++) {
$off = 0;
$tmp = GMailer::parse_data_packet("[".$matches[$i][1]."]", $off);
if (array_key_exists($tmp[0], $packets) || ($tmp[0]=="mi"||$tmp[0]=="mb"||$tmp[0]=="di")) {
// Added cl as alternate contact datapack; by Neerav; 15 June 2005
if ($tmp[0]=="t" || $tmp[0]=="ts" || $tmp[0]=="a" || $tmp[0]=="cl")
$packets[$tmp[0]] = array_merge($packets[$tmp[0]], array_slice($tmp, 1));
if ($tmp[0]=="mi" || $tmp[0]=="mb" || $tmp[0]=="di") {
if (array_key_exists("mg", $packets))
array_push($packets["mg"],$tmp);
else
$packets["mg"] = array($tmp);
}
} else {
$packets[$tmp[0]] = $tmp;
}
}
$this->raw = $packets;
return 1;
}
}
/**
* Class GMailSnapshot allows you to read information about Gmail in a structured way.
*
* There is no creator for this class. You must use {@link GMailer::getSnapshot()} to obtain
* a snapshot.
*
* @package GMailer
*/
class GMailSnapshot {
var $created;
/**
* Constructor.
*
* Note: you are not supposed to create a GMailSnapshot object yourself. You should
* use {@link GMailer::getSnapshot()} and/or {@link GMailer::webClip()} instead.
*
* @return GMailSnapshot
* @param constant $type
* @param array $raw
*/
function GMailSnapshot($type, $raw, $use_session, $raw_html) {
// input: raw packet generated by GMailer
// Invalid datapack checking
// snapshot_error Added; by Neerav; 3 Aug 2005
// Added http errors; by Neerav; 16 Sept 2005
if ((!is_array($raw)) or (count($raw) == 0)) {
$this->created = 0;
if (ereg('gmail_error=([0-9]{3})',$raw_html,$matches)) {
$this->snapshot_error = $matches[1];
if ($matches[1] != 500) {
Debugger::say("libgmailer: Gmail http error (".$matches[1]."), dump RAW HTML:\n".print_r($raw_html,true));
}
/* $this->snapshot_error_no = $matches[1]; */
/* ereg('<p><font size="-1">(.*?)</font></p>',$raw_html,$matches); */
/* $this->snapshot_error = $matches[1]; */
} elseif (ereg('<title>([0-9]{3}) Server Error</title>',$raw_html,$matches)) {
$this->snapshot_error = $matches[1];
if ($matches[1] != 502) {
Debugger::say("libgmailer: Gmail http error (".$matches[1]."), dump RAW HTML:\n".print_r($raw_html,true));
}
} elseif (strpos($raw_html,'500 Internal Server Error') !== false) {
$this->snapshot_error = 500;
} elseif (strpos($raw_html,'gmail_error=8;') !== false) {
$this->snapshot_error = 'lockdown';
} elseif (strpos($raw_html,'gmail_error=7;') !== false) {
$this->snapshot_error = '404';
} elseif (strpos($raw_html,'gmail_error=') !== false) {
$this->snapshot_error = "Unknown gmail error";
Debugger::say("libgmailer: unknown gmail error, dump RAW HTML:\n".print_r($raw_html,true));
} elseif (strpos($raw_html,'top.location="https://www.google.com/accounts/ServiceLogin') !== false) {
// Added error; by Neerav; 12 Oct 2005
//libgmailer: Gmail redirect to login screen
$this->snapshot_error = "libg110";
} elseif ($raw_html == "") {
$this->snapshot_error = "No response from Gmail";
} elseif (!is_array($raw)) {
$this->snapshot_error = "Invalid response from Gmail (not an array)";
Debugger::say("libgmailer: invalid datapack -- not an array, dump RAW HTML:\n".print_r($raw_html,true));
} elseif (count($raw) == 0) {
$this->snapshot_error = "Invalid response from Gmail (empty)";
}
return null;
}
// Gmail version
if (isset($raw["v"][1])) $this->gmail_ver = $raw["v"][1];
//$raw["v"][2] // What is this? Another version number?
//$raw["v"][3] // What is this?
// IdentificationKey (ik)
// Added by Neerav; 6 July 2005
if ($use_session) {
if (!isset($_SESSION['id_key']) or ($_SESSION['id_key'] == "")) {
Debugger::say("Snapshot: Using Sessions, saving id_key(ik)...");
if (isset($raw["ud"][3])) {
$_SESSION['id_key'] = $raw["ud"][3];
Debugger::say("Snapshot: Session id_key saved: " . $_SESSION['id_key']);
} else {
Debugger::say('Snapshot: Session id_key NOT saved. $raw["ud"][3] not found.');
}
}
} else {
if (!isset($_COOKIE[GM_COOKIE_IK_KEY]) or ($_COOKIE[GM_COOKIE_IK_KEY] == 0)) {
Debugger::say("Snapshot: Using Cookies, saving id_key(ik)...");
if (isset($raw["ud"][3])) {
if (strpos($_SERVER["HTTP_HOST"],":"))
$domain = substr($_SERVER["HTTP_HOST"],0,strpos($_SERVER["HTTP_HOST"],":"));
else
$domain = $_SERVER["HTTP_HOST"];
Debugger::say("Saving id_key as cookie ".GM_COOKIE_IK_KEY." with domain=".$domain);
/* header("Set-Cookie: ".GM_COOKIE_IK_KEY."=".base64_encode($raw["ud"][3])."; Domain=".$domain.";"); */
setcookie(GM_COOKIE_IK_KEY, base64_encode($raw["ud"][3]), time()+GM_COOKIE_TTL, "", $domain);
Debugger::say("Snapshot: Cookie id_key saved: ".GM_COOKIE_IK_KEY."=".base64_encode($raw["ud"][3]));
} else {
Debugger::say('Snapshot: Cookie id_key NOT saved. $raw["ud"][3] not found.');
}
}
}
// other "UD"
// your app SHOULD cache this in session or cookie for use across pages
// as the info is not always available for reference
// Added by Neerav; 6 July 2005
if (isset($raw["ud"])) {
$this->gmail_email = $raw["ud"][1]; // account email address; Added by Neerav; 6 May 2005
//$raw["ud"][2]; // keyboard shortcuts
//$raw["ud"][3]; // Identification Key, set above
//$raw["ud"][4]; // link/url to Contacts
//$raw["ud"][5]; // What is this?
//$raw["ud"][6]; // What is this?
//$raw["ud"][7]; // What is this?
//$raw["ud"][8]; // link/url to Calendar
//$raw["ud"][9]; // link/url to manage account (password)
$this->service_name = $raw["ud"][10]; // service name: gmail or hosted domain/custom name for hosted domains; Added by Neerav; 19 Jan 2007
//$raw["ud"][11]; // What is this? Array of increasing numbers
//$raw["ud"][12]; // What is this? Array of 0s and 1s
}
// su
//$raw["su"][1] // What is this? (matches $raw["v"][2])
//$raw["su"][2][1 through 6] // What is this? (?? array of text strings for invites)
// The service logo url: gmail or hosted domain's custom logo
// Added by Neerav; 19 Jan 2007
// your app SHOULD cache this in session or cookie for use across pages
// it does not always displayed or available for reference
if (isset($raw["su"][2][1])) {
$this->service_logo = $raw["su"][2][1];
}
// cp
//$raw["cp"][1] // What is this? (always 1)
//$raw["cp"][2] // What is this? (always 0) 1 for hosted domains?
//$raw["cp"][3] // What is this? (always 1)
// csm
//$raw["csm"][1] // What is this? (always 1)
// cld
//$raw["cld"] // What is this? (empty)
// ss
//$raw["ss"][1][1] // custom style sheet for hosted domains
// adc
//$raw["adc"][1] // 0
//$raw["adc"][2] // array
//$raw["adc"][3] // 1
//$raw["adc"][4] // url to hosted domain signin page?
//$raw["adc"][5] // 1
//$raw["adc"][6] // 0
//$raw["adc"][7] // 0
//$raw["adc"][8] // 1
//$raw["adc"][9] //
//$raw["adc"][10] //
//$raw["adc"][11] // 0
//$raw["adc"][12] // 0
// COUntry
// Added by Neerav; 20 Dec 2005
// (12 Feb 2007) this always seems to be US or blank. :-( Not useful.
$this->country = ((isset($raw["cou"][1]))?$raw["cou"][1]:"");
// Google Accounts' name
// your app SHOULD cache this in session or cookie for use across pages
// it's bandwidth expensive to retrieve preferences just for this
// Added by Neerav; 2 July 2005
if (isset($raw["gn"][1])) $this->google_name = $raw["gn"][1];
// Signature
// your app SHOULD cache this in session or cookie for use across pages
// it's bandwidth expensive to retrieve preferences just for this
// Added by Neerav; 6 July 2005
if (isset($raw["p"])) {
for ($i = 0; $i < count($raw["p"]); $i++) {
if ($raw["p"][$i][0] == "sx_sg") {
// can be undefined ?!?!
$this->signature = (isset($raw["p"][$i][1])) ? $raw["p"][$i][1] : "" ;
break;
}
}
}
// Invites
if (isset($raw["i"][1]) and $raw["i"][1] >= 0) {
$this->have_invit = $raw["i"][1];
} else {
$this->have_invit = 0;
}
// QUota information
if (isset($raw["qu"])) {
// Space used as xx MB
$this->quota_mb = $raw["qu"][1];
// Total space allotted as xxxx MB
$this->quota_tot = $raw["qu"][2]; // Added by Neerav; 6 May 2005
// Space used as xx%
$this->quota_per = $raw["qu"][3]; // Added by Neerav; 6 May 2005
// html color as #aabbcc (normally a green color, but red when nearly full)
$this->quota_col = $raw["qu"][4]; // Added by Neerav; 6 July 2005
}
// Footer Tips or Fast Tips
// Added by Neerav; 6 July 2005
if (isset($raw["ft"][1])) $this->gmail_tip = $raw["ft"][1];
// cfs; Compose from source
// Added by Neerav: 30 Aug 2005; Modified by Gan: 9 Sep 2005
$this->personality = array();
$this->personality_unverify = array();
if (isset($raw["cfs"])) {
if (isset($raw["cfs"][1])) {
$person_verified = count($raw["cfs"][1]);
for($i = 0; $i < $person_verified; $i++) {
$this->personality[] = array(
"name" => $raw["cfs"][1][$i][0],
"email" => $raw["cfs"][1][$i][1],
"default" => (($raw["cfs"][1][$i][2]==0) ? false : true),
"reply-to" => ((isset($raw["cfs"][1][$i][3])) ? $raw["cfs"][1][$i][3] : ""), // [not available to everyone yet (Gan: 9 Sept)]
"verified" => true
);
}
$person_unverified = count($raw["cfs"][2]);
for($i = 0; $i < $person_unverified; $i++) {
$this->personality_unverify[] = array(
"name" => $raw["cfs"][2][$i][0],
"email" => $raw["cfs"][2][$i][1],
"default" => (($raw["cfs"][2][$i][2]==0) ? false : true),
"reply-to" => ((isset($raw["cfs"][2][$i][3])) ? $raw["cfs"][2][$i][3] : ""), // [not available to everyone yet (Gan: 9 Sept)]
"verified" => false
);
}
}
}
// web clips and advertisements
$this->web_clips = array();
if (isset($raw["ad"]) and isset($raw["ad"][1][3])) {
/* $this->web_clips = */GmailSnapshot::web_clip_snapshot($raw["ad"][1][3]);
}
/* Debugger::say("final web clip: ".print_r($this->web_clips,true)); */
// What is this?
// $raw["df"][1] // shows ?false?
// $raw["ms"]
// $raw["e"]
// $raw["pod"]
// $raw["te"]
// $raw["csm"][1]
if ($type & (GM_STANDARD|GM_LABEL|GM_CONVERSATION|GM_QUERY)) {
// Added by Neerav; 6 May 2005
if (isset($raw["p"]) and !isset($this->signature)) {
for ($i = 1; $i < count($raw["p"]); $i++) {
if ($raw["p"][$i][0] == "sx_sg") {
// can be undefined ?!?!
$this->signature = (isset($raw["p"][$i][1])) ? $raw["p"][$i][1] : "" ;
break;
}
}
}
if (!isset($this->signature)) $this->signature = "";
// when a conversation does not exist, neither does ds; Fix by Neerav; 1 Aug 2005
if (isset($raw["ds"])) {
if (!is_array($raw["ds"])) {
$this->created = 0;
$this->snapshot_error = "libgmailer: invalid datapack";
return null;
}
// Fix for change in format of unread messages in some accounts; by Neerav; 2 Feb 2006
if (is_array($raw["ds"][1])) {
$this->std_box_new = array(0,0,0,0,0,0,0);
$std_boxes = array("inbox","starred","sent","drafts","all","spam","trash");
foreach ($raw["ds"][1] as $std_box) {
$name = $std_box[0];
$which_box = array_search($name,$std_boxes);
if ($which_box !== false and $which_box !== "") {
$this->std_box_new[$which_box] = $std_box[1];
}
}
} else {
$this->std_box_new = array_slice($raw["ds"],1);
}
} else {
$this->created = 0;
if (isset($raw["tf"])) { // a known error, as a status message, from Gmail
// usually a "this conversation no longer exists" status message
$this->snapshot_error = $raw["tf"][1];
} else {
$this->snapshot_error = "libgmailer: unknown but fatal datapack error";
Debugger::say("ds AND tf undefined, dumping raw: ". print_r($raw,true));
}
return null;
}
$this->label_list = array();
$this->label_new = array();
// Labels
// Last changed by Neerav; 12 July 2005
if ((isset($raw["ct"][1])) and (count($raw["ct"][1]) > 0)) {
foreach ($raw["ct"][1] as $v) {
array_push($this->label_list, $v[0]);
array_push($this->label_new, $v[1]);
}
} elseif (isset($raw["ct"]) and !isset($raw["ct"][1])) {
Debugger::say('ct[1] not set, raw[ct] dump: '.print_r($raw["ct"],true));
}
// Threads Summary
if (isset($raw["ts"])) {
$this->view = (GM_STANDARD|GM_LABEL|GM_QUERY);
$this->box_name = $raw["ts"][5]; // name of box/label/query
$this->box_total = $raw["ts"][3]; // total messages found
$this->box_pos = $raw["ts"][1]; // starting message number
// Added by Neerav; 6 July 2005
$this->box_display = $raw["ts"][2]; // max number of messages to display on the page
$this->box_query = $raw["ts"][6]; // gmail query for box
$this->queried_results = $raw["ts"][4]; // was this a search query (bool)
//$this->?? = $raw["ts"][7]; // what is this?? some id number?
//$this->?? = $raw["ts"][8]; // what is this?? total number of messages in account? or repeat of [3]
//$this->?? = $raw["ts"][9]; // what is this?? serial number, id number, VERY LONG!
//$this->?? = $raw["ts"][10]; // what is this?? always blank
}
// mailbox state/status (state of the mailbox [threads summary] which probably remembers the last message received, etc
if (isset($raw["ms"][1])) {
$this->mailbox_state = $raw["ms"][1];
} else {
$this->mailbox_state = "";
}
$this->box = array();
if (isset($raw["t"])) {
foreach ($raw["t"] as $t) {
if ($t == "t") continue;
// Fix for 12 OR 13 fields!!; by Neerav; 23 July 2005
//$less = (count($t) == 12) ? 1 : 0 ;
// Changed to 12 or 13 vs. 14 fields; by Neerav; 25 Oct 2005
// is this permanent?? did Gmail increase the size of the array?? Why? What?
//$less = (count($t) == 12 or count($t) == 13) ? 1 : 0 ;
// Gmail increased the length of the array on/before 25 Oct 2005
// Instead of relying on array size, we look for the labels array
// Update: (15 Apr 2006) now there are upto 16 fields.
if (count($t) < 12) {
$less = 0;
$tb["id"] = $t[0];
$tb["is_read"] = 0;
$tb["is_starred"]= 0;
$tb["date"] = "(error)";
$tb["sender"] = "(error)";
$tb["flag"] = "";
$tb["subj"] = "(error)";
//$tb["snippet"] = ((count($t) == 12) ? "" : $t[7] );
$tb["snippet"] = "(error)";
$tb["msgid"] = "(error)";
$tb["labels"] = array(); // gives an array even if 0 labels
$tb["attachment"]= array();
//$tb["??"] = $t[10-$less];
//$tb["??"] = $t[11-$less];
$tb["long_date"] = "(error)";
$tb["long_time"] = "(error)";
$tb["is_chat"] = 0;
$tb["chat_length"] = "";
//$tb["??"] = $t[15-$less];
array_push($this->box, $tb);
continue;
} elseif (is_array($t[8])) {
// normal
$less = 0;
} elseif (is_array($t[7])) {
// without snippet
$less = 1;
} elseif (is_array($t[9])) {
// just here for future compatibility
$less = -1;
} elseif (is_array($t[6])) {
// just here for future compatibility
$less = 2;
} else {
$less = 0;
}
// Added by Neerav; 6 July 2005
$long_date = "";
$long_time = "";
$date_time = explode("_",$t[12-$less]);
if (isset($date_time[0])) $long_date = $date_time[0];
if (isset($date_time[1])) $long_time = $date_time[1];
// Added labels for use in multiple languages; by Neerav; 7 Aug 2005
//$label_array_lang = $t[8-$less];
// Added by Neerav; 6 July 2005
// Gives an array of labels and substitutes the standard names
// Changed to be language compatible; by Neerav; 8 Aug 2005
$label_array = array();
foreach($t[8-$less] as $label_entry) {
switch ($label_entry) {
//case "^i": $label_array[] = "Inbox"; break;
//case "^s": $label_array[] = "Spam"; break;
//case "^k": $label_array[] = "Trash"; break;
case "^t": /* Starred */ break;
//case "^r": $label_array[] = "Draft"; break;
default: $label_array[] = $label_entry; break;
}
}
$tb = array();
$tb["id"] = $t[0];
$tb["is_read"] = (($t[1] == 1) ? 1 : 0);
$tb["is_starred"]= (($t[2] == 1) ? 1 : 0);
$tb["date"] = strip_tags($t[3]);
$tb["sender"] = strip_tags($t[4],"<b>");
$tb["flag"] = $t[5];
$tb["subj"] = strip_tags($t[6],"<b>");
//$tb["snippet"] = ((count($t) == 12) ? "" : $t[7] );
$tb["snippet"] = (($less) ? "" : $t[7] );
$tb["msgid"] = $t[10-$less];
// Added by Neerav; 7 Aug 2005
//$tb["labels_lang"]= $label_array_lang; // for use with languages
// Added/Changed by Neerav; 6 July 2005
$tb["labels"] = $label_array; // gives an array even if 0 labels
$tb["attachment"]= ((strlen($t[9-$less]) == 0) ? array() : explode(",",$t[9-$less]));// Changed to give an array even if 0 attachments
//$tb["??"] = $t[10-$less]; // what is this?? repeat of id??
//$tb["??"] = $t[11-$less]; // what is this?? always 0
$tb["long_date"] = $long_date; // added
$tb["long_time"] = $long_time; // added
// some accounts have chat, some do not
if (isset($t[13-$less])) {
$tb["is_chat"] = $t[13-$less]; // Added by (Gmail) Neerav; 16 Feb 2006;
$tb["chat_length"] = $t[14-$less]; // Added by (Gmail) Neerav; 16 Feb 2006;
//$tb["??"] = $t[15-$less]; // Added by (Gmail) Neerav; 16 Feb 2006; what is this?? always 0
} else {
$tb["is_chat"] = 0; // Added by (Gmail) Neerav; 16 Feb 2006;
$tb["chat_length"] = ""; // Added by (Gmail) Neerav; 16 Feb 2006;
//$tb["??"] = $t[15-$less]; // Added by (Gmail) Neerav; 16 Feb 2006; what is this?? always 0
}
array_push($this->box, $tb);
}
}
// Conversation Summary
if (isset($raw["cs"])) {
//Debugger::say("cs exists: ".print_r($raw["cs"],true));
//Debugger::say("cs exists, dumping raw: ".print_r($raw,true));
// Fix for 14 OR 12 fields!!; by Neerav; 25 July 2005
$less_cs = (count($raw["cs"]) == 12) ? 2 : 0 ;
// Fix for variable fields based on field type; by Neerav; 21 Apr 2006
/* if (is_array($raw["cs"][5]) and is_array($raw["cs"][6])) { */
/* $less_cs = 0; */
/* } elseif (is_array($raw["cs"][6]) and is_array($raw["cs"][7])) { */
/* $less_cs = -1; */
/* } else { */
/* $less_cs = 0; */
/* } */
/* $less_cs = (count($raw["cs"]) == 12) ? 2 : 0 ; */
/* if (count($raw["cs"]) > 14) Debugger::say("extra cs fields: ".print_r($raw["cs"],true)); */
$this->view = GM_CONVERSATION;
$this->conv_id = $raw["cs"][1];
$this->conv_title = $raw["cs"][2];
// $raw["cs"][3] // what is this?? escape/html version of 2?
// $raw["cs"][4] // what is this?? empty
// $raw["cs"][5] // (array) conversation labels, below
// $raw["cs"][6] // what is this?? array
// $raw["cs"][7] // what is this?? integer/bool?
$this->conv_total = $raw["cs"][8];
// (count($t) == 14) $raw["cs"][9] // may be missing! what is this?? long id number?
// (count($t) == 14) $raw["cs"][10] // may be missing! what is this?? empty
// $raw["cs"][11-$less_cs] // may be 9 what is this?? repeat of id 1?
// $raw["cs"][12-$less_cs] // may be 10 what is this?? array
// $raw["cs"][13-$less_cs] // may be 11 what is this?? integer/bool?
// $raw["cs"][14-$less_cs] // always one less than 8 (one less than total messages in conv)
// -1 for drafts?
$this->conv_labels = array ();
$this->conv_starred = false;
// Added labels for use in multiple languages; by Neerav; 7 Aug 2005
//$this->conv_labels_lang = $raw["cs"][5]; // for use with languages
// Changed to give translated label names; by Neerav; 6 July 2005
// Changed back to be language compatible; by Neerav; 8 Aug 2005
//$this->conv_labels_temp = (count($raw["cs"][5])==0) ? array() : $raw["cs"][5];
$temp_array = $raw["cs"][5];
foreach($raw["cs"][5] as $label_entry) {
switch ($label_entry) {
//case "^i": $this->conv_labels[] = "Inbox"; break;
//case "^s": $this->conv_labels[] = "Spam"; break;
//case "^k": $this->conv_labels[] = "Trash"; break;
case "^t": $this->conv_starred = true; break;
//case "^r": $this->conv_labels[] = "Draft"; break;
default: $this->conv_labels[] = $label_entry; break;
}
}
$this->conv = array();
if (!isset($raw["mg"])) {
// Added error; by Neerav; 24 Sept 2005
// libg102 error: a specific message has been requested, but must actually be
// taken from the thread (message may be a draft or other expanded message)
$this->snapshot_error = "libg102";
$this->created = 0;
return null;
} else {
$mg_count = count($raw["mg"]);
for ($i = 0; $i < $mg_count; $i++) {
if ($raw["mg"][$i][0] == "mb" && $i > 0) {
if (isset($raw["mg"][$i][1])) {
if (!isset($b)) $b = array(); // added by Neerav; 4 Apr 2007
$b["body"] .= $raw["mg"][$i][1];
}
if (isset($raw["mg"][$i][2])) {
if ($raw["mg"][$i][2] == 0) {
array_push($this->conv, $b);
unset($b);
}
} else {
// Added error; by Neerav; 9 Feb 2006
// THIS ERROR OCCURS BECAUSE OF IMPROPER DATAPACK PARSING
$this->snapshot_error = "libg101";
$this->created = 0;
return null;
}
} elseif (($raw["mg"][$i][0] == "mi") or ($raw["mg"][$i][0] == "di")) {
// to account for an added 20th index with a phishing warning
// Added by Neerav; 1 Dec 2005
/* $more = (isset($raw["mg"][$i][26]) and is_array($raw["mg"][$i][26])) ? 1 : 0 ; */
// Changed by Neerav; 24 Mar 2006
$more = (isset($raw["mg"][$i][20]) and strpos($raw["mg"][$i][20],"<font color=\"#ffffff\">") !== false) ? 1 : 0 ;
// Changed to merge "di" and "mi" routines; by Neerav; 11 July 2005
if (isset($b)) {
array_push($this->conv, $b);
unset($b);
}
$b = array();
// $raw["mg"][$i][0] is mi or di
$b["mbox"] = $raw["mg"][$i][1]; // Added by Neerav; 11 July 2005
$b["is_trashed"] = ((int)$raw["mg"][$i][1] & 128) ? true : false; // Added by Neerav; 23 Feb 2006
$b["is_html"] = ((int)$raw["mg"][$i][1] &(16|32)) ? true : false; // Added by Neerav; 23 Feb 2006
$b["html_images"] = ((int)$raw["mg"][$i][1] & 32) ? true : false; // Added by Neerav; 23 Feb 2006
$b["index"] = $raw["mg"][$i][2];
$b["id"] = $raw["mg"][$i][3];
$b["is_star"] = $raw["mg"][$i][4];
if ($b["is_star"] == 1) $this->conv_starred = true;
$b["draft_parent"] = $raw["mg"][$i][5]; // was only defined in draft, now both; Changed by Neerav; 11 July 2005
$b["sender"] = $raw["mg"][$i][6];
$b["sender_short"] = $raw["mg"][$i][7]; // Added by Neerav; 11 July 2005
/* $b["sender_email"] = str_replace("\"", "", $raw["mg"][$i][8]); // remove annoying d-quotes in address */
$b["sender_email"] = $raw["mg"][$i][8];
// 9 is the short stringed names, e.g. "me, john, bob"
//$b["recv"] = strip_tags($raw["mg"][$i][9]);
// gmail changed from string to array and added email address and conversation number; by Neerav; 25 July 2006
if (is_string($raw["mg"][$i][9])) {
$b["recv"] = strip_tags($raw["mg"][$i][9]);
} else {
$b["recv"] = "";
$count_9 = count($raw["mg"][$i][9]);
for ($mg9i = 0; $mg9i < $count_9; $mg9i++) {
$count_sub9 = count($raw["mg"][$i][9][$mg9i]);
if ($count_sub9 > 0) {
for ($mg9j = 0; $mg9j < $count_sub9; $mg9j++) {
if (isset($raw["mg"][$i][9][$mg9i][$mg9j][0])) {
$b["recv"] .= $raw["mg"][$i][9][$mg9i][$mg9j][0]. ", ";
}
}
}
$b["recv"] = preg_replace("/\, $/","",$b["recv"]);
}
//Debugger::say("raw[mg][x][9]:\n".print_r($raw["mg"][$i][9],true)."\nFixed: ".$b["recv"]);
}
//Debugger::say("raw[mg][x][9]:\n".print_r($raw["mg"][$i][9],true)."\n\nraw[mg][x][11]:\n".print_r($raw["mg"][$i][11],true));
$b["recv_email"] = $raw["mg"][$i][11];
$b["dt_easy"] = $raw["mg"][$i][10];
if ( isset($raw["mg"][$i][15])
and isset($raw["mg"][$i][16])
and isset($raw["mg"][$i][13])
and isset($raw["mg"][$i][14])
and isset($raw["mg"][$i][14])
and isset($raw["mg"][$i][12])
) {
$b["cc_email"] = $raw["mg"][$i][12]; // was only defined in draft, now both; Changed by Neerav; 11 July 2005
$b["bcc_email"] = $raw["mg"][$i][13]; // was only defined in draft, now both; Changed by Neerav; 11 July 2005
$b["reply_email"] = $raw["mg"][$i][14];
$b["dt"] = $raw["mg"][$i][15];
$b["subj"] = $raw["mg"][$i][16];
} else {
// Added error; by Neerav; 9 Jan 2006
// THIS ERROR OCCURS BECAUSE OF IMPROPER DATAPACK PARSING
$this->snapshot_error = "libg101";
$this->created = 0;
return null;
}
$b["snippet"] = $raw["mg"][$i][17];
$b["sender_in_contact"] = $raw["mg"][$i][19]; // (0,1) sender already in the contacts list; Added by Neerav; 6 Mar 2006
$b["attachment"] = array();
if (isset($raw["mg"][$i][18])) { // attachments
if (!is_array($raw["mg"][$i][18])) {
// Added error; by Neerav; 24 Sept 2005
// THIS ERROR OCCURS BECAUSE OF IMPROPER DATAPACK PARSING
$this->snapshot_error = "libg101";
$this->created = 0;
return null;
} else {
foreach ($raw["mg"][$i][18] as $bb) {
//Debugger::say("looking for thumbnails: ".$raw["ma"][1][1]);
array_push(
$b["attachment"],
array("id" => $bb[0],
"filename" => $bb[1],
"type" => str_replace("\"", "", $bb[2]), // updated to remove the "'s; by Neerav; 19 Jan 2006
"size" => $bb[3],
//,"" => $bb[4] // always -1, what is this??
//,"" => $bb[5] // looks like: f_ewm3qxd1 what is this??
// attachment has thumbnail; Added by Neerav; 22 Aug 2006
"has_thumb" => (isset($raw["ma"][1][1])
and (strpos($raw["ma"][1][1],"&disp=thd&attid=".$bb[0]."&") !== false
or
// updated the string to look for thumbnails; Neerav; 6 Oct 2006
strpos($raw["ma"][1][1],"attid=".$bb[0]."&disp=thd&") !== false
) ? 1 : 0)
)
);
if (!isset($bb[1])) {
Debugger::say("undefined attachment info, dumping message: ", print_r($raw["mg"][$i],true));
Debugger::say("undefined attachment info, dumping raw: ".print_r($raw,true));
Debugger::say("undefined attachment info, dumping raw_html: ".print_r($raw_html,true));
}
}
}
}
if ($raw["mg"][$i][0] == "mi") {
//
// message only
//
$b["is_draft"] = false;
$b["body"] = "";
$b["warning"] = (($more == 1) ? $raw["mg"][$i][20]: ""); // phishing WARNING from Gmail // Added by Neerav; 1 Dec 2005
// $raw["mg"][$i][20+$more]; // ?? repeated date in unix-like format with an _ // Added by Neerav; 11 July 2005
$b["quote_str"] = $raw["mg"][$i][21+$more];
$b["quote_str_html"]= $raw["mg"][$i][22+$more];
// Added the following indexes; Neerav; 1 Dec 2005
$b["mailed-by"] = $raw["mg"][$i][23+$more]; // Neerav; 15 Jan 2007; certified sender's domain for SENT messages
$b["signed-by"] = $raw["mg"][$i][24+$more]; // Neerav; 15 Jan 2007; certified sender's domain for RECEIVED messages
// $raw["mg"][$i][25+$more]; // always array(,,1) What is this??
// $raw["mg"][$i][26+$more]; // always blank What is this??
// $raw["mg"][$i][27+$more]; // array(,,0) or blank What is this??
// $raw["mg"][$i][28+$more]; // always 0 What is this??
// $raw["mg"][$i][29+$more]; // header: Sender (real sender: don't need this) // 6 Mar 2006
// $raw["mg"][$i][30+$more]; // header: Message-ID (don't need this in snapshot) // 3 Mar 2006
// $raw["mg"][$i][31+$more]; // always 0 What is this??
$b["to_custom_from"] = (isset($raw["mg"][$i][32+$more])?$raw["mg"][$i][32+$more]:""); // Custom From which this message was sent to
// $raw["mg"][$i][33+$more]; // always 0 What is this??
// $raw["mg"][$i][34+$more]; // In reply to...
// $raw["mg"][$i][35+$more]; // always 0 What is this??
} elseif ($raw["mg"][$i][0] == "di") {
//
// draft only
//
$b["is_draft"] = true;
$b["body"] = $raw["mg"][$i][20];
$b["mailed-by"] = "";
$b["signed-by"] = "";
$b["to_custom_from"]= $raw["mg"][$i][33];
// $raw["mg"][$i][21]; // ?? repeated date slightly different format // Added by Neerav; 11 July 2005
if (isset($raw["mg"][$i][22]) and isset($raw["mg"][$i][23])) {
$b["quote_str"] = $raw["mg"][$i][22];
$b["quote_str_html"]= $raw["mg"][$i][23];
} else {
// Added error; by Neerav; 9 Jan 2006
// THIS ERROR OCCURS BECAUSE OF IMPROPER DATAPACK PARSING
$this->snapshot_error = "libg101";
$this->created = 0;
return null;
}
// Added to match additions to "mi"; by Neerav; 1 Dec 2005
$b["warning"] = "";
}
}
}
}
if (isset($b)) array_push($this->conv, $b);
}
}
// Changed from elseif to if; by Neerav; 5 Aug 2005
if ($type & GM_CONTACT) {
$this->contacts = array();
$this->contact_groups = array(); // Added by Neerav; 20 Dec 2005
$this->contacts_total = 0; // Added by Neerav; 5 Jan 2006
// general contacts information; Added by Neerav; 5 Jan 2006
if (isset($raw["cls"])) {
$this->contacts_total = $raw["cls"][1]; // total number of contacts
//$raw["cls"][2] // array, type of contacts
//$raw["cls"][2][i][0] // Gmail code for type of contacts: p=frequent, a=all, l=group, s=search
//$raw["cls"][2][i][1] // Human readable button text for the above code type
$this->contacts_shown = $raw["cls"][3]; // Gmail code for type of contacts currently shown/retrieved
//$this->contacts_total = $raw["cls"][4] // is 4 ?? What is this??
}
// Added by Neerav; 29 June 2005
// Since gmail changes their Contacts array often, we need to see which
// latest flavor (or flavour) they are using!
// Some accounts use "a" for both lists and details
// whereas some accounts use "cl" for lists and "cov" for details
$type = "";
$c_grp_det = "";
if (isset($raw["a"])) {
Debugger::say("uses 'a' for contacts: ".print_r($raw,true));
$c_array = "a";
// determine is this is a list or contact detail
if ((count($raw["a"]) == 2) and isset($raw["a"][1][6])) {
$type = "detail";
$c_id = 0;
$c_name = 1;
$c_email = 3;
$c_groups = 4;
$c_notes = 5;
$c_detail = 6;
} else {
$c_email = 3;
$c_notes = 4;
$type = "list";
//$c_addresses = 5;
}
} elseif (isset($raw["cl"])) { // list
$c_array = "cl";
$c_email = 4;
$c_notes = 5;
$c_addresses = 6;
$type = "list";
} elseif (isset($raw["cov"])) { // contact detail in accounts using "cl"
$c_array = "cov";
$type = "detail";
$c_id = 1;
$c_name = 2;
$c_email = 4;
$c_groups = 6;
$c_notes = 7;
$c_detail = 8;
} elseif (isset($raw["clv"])) { // group detail in accounts using "cl" // added by Neerav; 6 Jan 2006
$c_array = "clv";
//$c_grp_det = "cle";
$type = "detail";
$c_id = 1;
$c_name = 2;
$c_email = 6;
$c_total = 3;
$c_detail = 5;
$c_members = 4;
$c_notes = 0;
} else {
array_push(
$this->contacts,
array("id" => "error",
"name" => "libgmailer Error",
"email" => "hide@address.com",
"is_group" => 0,
"notes" => "libgmailer could not find the Contacts information "
. "due to a change in the email service (again!). Please contact "
. "the author of this program (which uses libgmailer) for a fix."
)
);
}
// Changed by Neerav;
// from "a" to "cl" 15 June 2005
// from "cl" to whichever exists 29 June 2005
if ($type == "list") {
// An ordinary list of contacts
for ($i = 1; $i < count($raw["$c_array"]); $i++) {
$a = $raw["$c_array"][$i];
$b = array(
"id" => $a[1], // contact id; Added by Neerav; 6 May 2005
"name" => (isset($a[2])?$a[2]:""),
/* "email" => str_replace("\"", "", $a[$c_email]) // Last Changed by Neerav; 29 June 2005 */
"email" => $a[$c_email] // Last Changed by Neerav; 29 June 2005
);
// Last Changed by Neerav; 29 June 2005
if (isset($a[$c_notes])) {
// Contact groups support; 5 Jan 2006
if (is_array($a[$c_notes])) {
$b["notes"] = "";
$b["is_group"] = true;
// email addresses for groups are in a different location and format
// "Name" <hide@address.com>, "Name2" <hide@address.com>, etc
// and needs to be "simply" re-created for backwards compatibility
$gr_count = count($a[$c_notes]);
$group_addresses = array();
for ($gr_entry = 0; $gr_entry < $gr_count; $gr_entry++) {
$group_addresses[] = $a[$c_notes][$gr_entry][1];
}
$b["email"] = implode(", ",$group_addresses);
//$b["email"] = str_replace("\"", "", $a[$c_addresses]);
$b["group_names"] = $a[$c_email];
$b["group_total"] = $a[3];
$b["group_email"] = (count($a[$c_notes]) > 0) ? $a[$c_addresses] : array();
} else {
$b["notes"] = $a[$c_notes];
$b["is_group"] = false;
$b["groups"] = $a[$c_addresses];
}
}
array_push($this->contacts, $b);
}
} elseif ($type == "detail") {
//Debugger::say("raw: ".print_r($raw,true));
$details = array();
if ($c_array == "clv") {
// Added by Neerav; 6 Jan 2006
// Group details
$cov["is_group"] = true; // is this a group?
$cov["id"] = $raw["$c_array"][1][$c_id]; // group id
$cov["name"] = $raw["$c_array"][1][$c_name]; // group name
$gr_count = count($raw["$c_array"][1][$c_detail]);
$cov["group_names"] = $raw["$c_array"][1][$c_members]; // string of names of group members
$cov["group_total"] = $raw["$c_array"][1][$c_total]; // string, total number of members in group
/* $cov["group_email"] = str_replace("\"", "", $raw["$c_array"][1][$c_email]); // formatted list of addresses as: Name <address> */
$cov["group_email"] = (isset($raw["$c_array"][1][$c_email])) ? $raw["$c_array"][1][$c_email] : ""; // formatted list of addresses as: Name <address>
$cov["notes"] = ""; // no notes for groups... yet!
$group_addresses = array(); // string of flattened email addresses
$cov["members"] = array(); // array of group members
for ($gr_entry = 0; $gr_entry < $gr_count; $gr_entry++) {
$group_addresses[] = $raw["$c_array"][1][$c_detail][$gr_entry][1];
$cov["members"][] = array(
"id" => $raw["$c_array"][1][$c_detail][$gr_entry][0],
"name" => (isset($raw["$c_array"][1][$c_detail][$gr_entry][2])?$raw["$c_array"][1][$c_detail][$gr_entry][2]:""),
"email" => $raw["$c_array"][1][$c_detail][$gr_entry][1]
);
}
$cov["email"] = (count($group_addresses) > 0) ? implode(", ",$group_addresses) : "";
} else {
// Added by Neerav; 1 July 2005
// Contact details (advanced contact information)
// used when a contact id was supplied for retrieval
$cov = array();
$cov["is_group"]= false;
$cov["id"] = $raw["$c_array"][1][$c_id];
$cov["name"] = $raw["$c_array"][1][$c_name];
/* $cov["email"] = str_replace("\"", "", $raw["$c_array"][1][$c_email]); */
$cov["email"] = $raw["$c_array"][1][$c_email];
$cov["groups"] = $raw["$c_array"][1][$c_groups];
if (isset($raw["$c_array"][1][$c_notes][0])) {
$cov["notes"] = ($raw["$c_array"][1][$c_notes][0] == "n") ? $raw["$c_array"][1][$c_notes][1] : "";
} else {
$cov["notes"] = "";
}
$num_details = count($raw["$c_array"][1][$c_detail]);
if ($num_details > 0) {
for ($i = 0; $i < $num_details; $i++) {
$details[$i][] = array(
"type" => "detail_name",
"info" => $raw["$c_array"][1][$c_detail][$i][0]
);
if (isset($raw["$c_array"][1][$c_detail][$i][1])) {
$temp = $raw["$c_array"][1][$c_detail][$i][1];
} else {
$temp = array();
Debugger::say('$raw['.$c_array.'][1]['.$c_detail.']['.$i.'][1] not defined libgmailer: 2548, dumping raw: '. print_r($raw,true));
}
for ($j = 0; $j < count($temp); $j += 2) {
switch ($temp[$j]) {
case "p": $field = "phone"; break;
case "e": $field = "email"; break;
case "m": $field = "mobile"; break;
case "f": $field = "fax"; break;
case "b": $field = "pager"; break;
case "i": $field = "im"; break;
case "d": $field = "company"; break;
case "t": $field = "position"; break; // t = title
case "o": $field = "other"; break;
case "a": $field = "address"; break;
default: $field = $temp[$j]; break; // default to the field type
}
$details[$i][] = array(
"type" => $field,
"info" => $temp[$j+1]
);
}
}
}
$cov["details"] = $details;
}
array_push($this->contacts, $cov);
}
// Contact groups
// Added by Neerav; 20 Dec 2005
if (isset($raw["cla"])) {
for ($i = 1; $i < count($raw["cla"][1]); $i++) {
$a = $raw["cla"][1][$i];
$b = array(
"id" => $a[0],
"name" => $a[1],
/* "addresses" => ((isset($a[2])) ? str_replace("\"", "", $a[2]) : "") */
"addresses" => ((isset($a[2])) ? $a[2] : "")
);
array_push($this->contact_groups, $b);
}
}
$this->view = GM_CONTACT;
}
// Changed from elseif to if; by Neerav; 5 Aug 2005
if ($type & (GM_PREFERENCE)) {
// go to Preference Panel
// Added by Neerav; 6 July 2005
if (isset($raw["pp"][1])) {
switch ($raw["pp"][1]) {
case "g": $this->goto_pref_panel = "general"; break;
case "l": $this->goto_pref_panel = "labels"; break;
case "f": $this->goto_pref_panel = "filters"; break;
default: $this->goto_pref_panel = $raw["pp"][1]; break;
}
}
// SETTINGS (NON-Filters, NON-Labels)
// Added by Neerav; 29 Jun 2005
$this->setting_gen = array();
$this->setting_fpop = array();
$this->setting_other = array();
$this->setting_mobile = array();
$this->setting_chat = array();
if (isset($raw["p"])) {
// GENERAL SETTINGS
$gen = array(
//"use_cust_name" => 0,
"name_google" => ((isset($raw["gn"][1])) ? $raw["gn"][1] : ""),
//"name_display" => "",
//"use_reply_to" => 0,
//"reply_to" => "",
"language" => "en",
"page_size" => 25,
"shortcuts" => 0,
"p_indicator" => 0,
"show_snippets" => 0,
"use_signature" => 0,
"signature" => "",
"encoding" => 0,
"vacation_enabled" => 0,
"vacation_subject" => "",
"vacation_message" => "",
"vacation_contact" => 0,
"my_pict_visible" => 1,
"contact_pict_visible" => 0
);
// FORWARDING AND POP
$fpop = array(
"forward" => 0,
"forward_to" => "",
"forward_action"=> "selected",
"pop_enabled" => 0,
"pop_action" => 0,
"pop_on_since" => ""
);
// MOBILE
$mobile = array(
"display_boxes" => array("inbox","starred","sent","drafts","all","spam","trash")
);
// CHAT
$chat = array(
"save_chat" => 0, // added by Neerav; 10 Feb 2006
// added by Neerav; 6 Sept 2006
"new_chat_sound" => 0,
"quick_cont_bottom" => 0,
"quick_cont_length" => 10,
"quick_cont_auto_add" => 0,
"expand_chat_box" => 1
);
// OTHER
$other = array(
"google_display_name" => (isset($raw["gn"][1])?$raw["gn"][1]:""),
"google_reply_to" => "",
"expand_labels" => 1,
"expand_invites" => 1,
"expand_talk" => 1,
"reply_from_sent" => 0,
"rich_text" => 0, // not used yet or has been removed
"save_chat" => 0 // added by Neerav; 10 Feb 2006
);
if (isset($raw["gn"][1])) {
$gen["name_google"] = $raw["gn"][1];
}
// pod, Pop On (since) Date
if (isset($raw["pod"][1])) {
$fpop["pop_on_since"] = $raw["pod"][1];
}
for ($i = 1; $i < count($raw["p"]); $i++) {
$pref = $raw["p"][$i][0];
$value = (isset($raw["p"][$i][1])) ? $raw["p"][$i][1] : "";
switch ($pref) {
// GENERAL SETTINGS
//case "sx_dn": $gen["name_display"] = $value; break; // (string) name on outgoing mail (display name)
//case "sx_rt": $gen["reply_to"] = $value; break; // (string) reply to email address
case "sx_dl": $gen["language"] = $value; break; // (string) display language
case "ix_nt": $gen["page_size"] = $value; break; // (integer) msgs per page (maximum page size)
case "bx_hs": $gen["shortcuts"] = $value; break; // (boolean) keyboard shortcuts {0 = off, 1 = on}
case "bx_sc": $gen["p_indicator"] = $value; break; // (boolean) personal level indicators {0 = no indicators, 1 = show indicators}
case "bx_ns": $gen["show_snippets"] = !$value; break; // (boolean) no snippets {0 = show snippets, 1 = no snippets}
// we INVERSE this for convenience
case "sx_sg": $gen["signature"] = $value; break; // (string) signature
case "bx_en": $gen["encoding"] = $value; break; // (boolean) outgoing message encoding {0 = default, 1 = utf-8}
// added by Neerav; 20 Dec 2005
case "bx_ve": $gen["vacation_enabled"] = $value; break; // (boolean) vacation message enabled {0 = OFF, 1 = ON}
case "sx_vs": $gen["vacation_subject"] = $value; break; // (string) vacation message subject
case "sx_vm": $gen["vacation_message"] = $value; break; // (string) vacation message text
case "bx_vc": $gen["vacation_contact"] = (($value == "true" or $value === true) ? true : false); break; // (string to boolean) vacation message, send only to contacts list
// added by Neerav; 13 Sep 2006
case "ix_pp": $gen["my_pict_visible"] = $value; break; // (boolean) My Picture visibility {0 = all Gmail users, 1 = only people can chat with}
case "bx_pd": $gen["contact_pict_visible"] = $value; break; // (boolean) Visibility of Contacts' Pictures {0 = show all, 1 = show only what I chose}
// FORWARDING AND POP
case "sx_em": $fpop["forward_to"] = $value; break; // (string) forward to email
case "sx_at": $fpop["forward_action"] = $value; break; // (string) forwarding action {selected (keep), archive, trash}
case "bx_pe": $fpop["pop_enabled"] = $value; break; // (integer) pop enabled {0 = disabled, 2 = enabled from now, 3 = enable all}
case "ix_pd": $fpop["pop_action"] = $value; break; // (integer) action after pop access {0 = keep, 1 = archive, 2 = trash}
// SIDE BOXES
case "bx_show0": $other["expand_labels"] = $value; break; // (boolean) labels box {0 = collapsed, 1 = expanded}
case "bx_show1": $other["expand_invites"] = $value; break; // (boolean) invite box {0 = collapsed, 1 = expanded}
case "bx_show3": $other["expand_talk"] = $value;
$chat["expand_chat_box"] = $value;
break; // (boolean) gtalk box {0 = collapsed, 1 = expanded}
// ACCOUNT
case "bx_rf": $other["reply_from_sent"] = $value;
break; // (boolean) use reply from [sent] {0 = use default address, 1 = use address message was sent to}
// added by Neerav; 4 Mar 2006
case "sx_dn": $other["google_display_name"] = $value;
break; // (string) Google accounts "from" display name
case "sx_rt": $other["google_reply_to"] = $value;
break; // (string) Google accounts "from" reply-to address
// Chat
// added by Neerav; 10 Feb 2006
case "ix_ca": $chat["save_chat"] = $value;
$other["save_chat"] = $value;
break; // (boolean) save chat archive {0 = off, 1 = on}
// added by Neerav; 26 Feb 2006
// updated by Neerav; 6 Sept 2006
case "ix_ql": $chat["quick_cont_length"] = $value; break; // (integer)
case "bx_aa": $chat["quick_cont_auto_add"] = $value; break; // (boolean)
case "bx_lq": $chat["quick_cont_bottom"] = $value; break; // (boolean)
case "bx_sn": $chat["new_chat_sound"] = $value; break; // (boolean)
// MOBILE
// added by Neerav; 20 Dec 2005
case "sx_pf": if ($value != "") {
$mobile = array();
$temp_mobile = explode('#,~',$value);
for ($mob = 0; $mob < count($temp_mobile); $mob++) {
if ($temp_mobile[$mob] != "") $mobile['display_boxes'][] = $temp_mobile[$mob];
}
}
break;
// OTHER
// not used yet or has been removed from Gmail
case "bx_cm": $other["rich_text"] = $value; break; // (boolean) rich text composition {0 = plain text, 1 = rich text}
// added by Neerav; 20 Dec 2005
//case "bx_aa": $other["unknown"] = $value; break; //
default: $other["$pref"] = $value; break;
}
}
// set useful implicit boolean settings
//if ($gen["name_display"] != "") $gen["use_cust_name"] = 1;
//if ($gen["reply_to"] != "") $gen["use_reply_to"] = 1;
if ($gen["signature"] != "") $gen["use_signature"] = 1;
if ($fpop["forward_to"] != "") $fpop["forward"] = 1;
$this->setting_gen = $gen;
$this->setting_fpop = $fpop;
$this->setting_other = $other;
$this->setting_mobile = $mobile;
$this->setting_chat = $chat;
}
// LABELS
// Added $list_created to prevent overwriting of label_list; by Neerav; 27 April 2006
if (!isset($this->label_list)) {
$this->label_list = array();
$list_created = true;
} else {
$list_created = false;
}
$this->label_total = array();
if (isset($raw["cta"][1])) {
foreach ($raw["cta"][1] as $v) {
if ($list_created) array_push($this->label_list, $v[0]);
array_push($this->label_total, $v[1]);
}
} elseif (isset($raw["cta"])) {
Debugger::say('cta[1] not set, printing cta: '.print_r($raw["cta"],true));
}
// FILTERS
$this->filter = array();
if (isset($raw["fi"][1])) {
foreach ($raw["fi"][1] as $fi) {
// Changed/Added by Neerav; 23 Jun 2005
// filter rules/settings
// (The "() ? :" notation is used because empty/false fields at the end of an
// array are not always defined)
$b = array(
// (integer) filter id number
"id" => $fi[0],
// (string) gmail's filter summary
"query" => ((isset($fi[1])) ? $fi[1] : ""),
// (string) from field has...
"from" => ((isset($fi[2][0])) ? $fi[2][0] : ""),
// (string) to field has...
"to" => ((isset($fi[2][1])) ? $fi[2][1] : ""),
// (string) subject has...
"subject" => ((isset($fi[2][2])) ? $fi[2][2] : ""),
// (string) msg has the words...
"has" => ((isset($fi[2][3])) ? $fi[2][3] : ""),
// (string) msg doesn't have the words...
"hasnot" => ((isset($fi[2][4])) ? $fi[2][4] : ""),
// (boolean) has an attachment
"hasattach" => ((isset($fi[2][5]) and ($fi[2][5] == "true" or $fi[2][5] === true)) ? true : false),
// (boolean) archive (skip the inbox)
"archive" => ((isset($fi[2][6]) and ($fi[2][6] == "true" or $fi[2][6] === true)) ? true : false),
// (boolean) apply star
"star" => ((isset($fi[2][7]) and ($fi[2][7] == "true" or $fi[2][7] === true)) ? true : false),
// (boolean) apply label
"label" => ((isset($fi[2][8]) and ($fi[2][8] == "true" or $fi[2][8] === true)) ? true : false),
// (string) label name to apply
"label_name"=> ((isset($fi[2][9])) ? $fi[2][9] : ""),
// (boolean) forward
"forward" => ((isset($fi[2][10]) and ($fi[2][10] == "true" or $fi[2][10] === true)) ? true : false),
// (string email) forward to email address
"forwardto" => ((isset($fi[2][11])) ? $fi[2][11]: ""),
// (boolean) trash the message
"trash" => ((isset($fi[2][12]) and ($fi[2][12] == "true" or $fi[2][12] === true)) ? true : false)
);
array_push($this->filter, $b);
}
}
$this->view = GM_PREFERENCE;
} /* else { */
/* $this->created = 0; */
/* $this->snapshot_error = "libgmailer: no snapshot type specified"; // Added by Neerav; 3 Aug 2005 */
/* return null; */
/* } */
$this->created = 1;
return 1;
}
/**
* Constructor.
*
* Note: you are not supposed to create a GMailSnapshot object yourself. You should
* use {@link GMailer::getSnapshot()} and/or {@link GMailer::webClip()} instead.
*
* @return GMailWebclipSnapshot
* @param array $raw
*/
function web_clip_snapshot($raw) {
$clips = array();
foreach ($raw as $webclip) {
if (count($webclip) == 10) {
$ad_site = 4;
$ad_date = 5;
$ad_sub = 6;
$ad_type = 8;
$ad_cat = 9;
} elseif (count($webclip) == 6) {
$ad_site = 0; // not really, but will be blank
$ad_date = 0; // not really, but will be blank
$ad_sub = 0; // not really, but will be blank
$ad_type = 4;
$ad_cat = 5;
} elseif (count($webclip) == 7) {
$ad_site = 4;
$ad_date = 0; // not really, but will be blank
$ad_sub = 0; // not really, but will be blank
$ad_type = 5;
$ad_cat = 6;
} else {
Debugger::say("odd web clips: ".print_r($webclip,true));
continue;
}
$clip = array();
//$clip[''] = $webclip[0]; // ??
//$clip[''] = $webclip[1]; // clip id??
$clip['url'] = $webclip[2];
$clip['title'] = $webclip[3];
$clip['site'] = (($ad_site != 0) ? $webclip[$ad_site]: "");
$clip['date'] = (($ad_date != 0) ? $webclip[$ad_date]: "");
$clip['sub'] = (($ad_sub != 0) ? $webclip[$ad_sub]: "");
//$clip[''] = (($less) ? "" : $webclip[7]); // ?? empty
$clip['type'] = $webclip[$ad_type]; // web clip, advertisement, gmail tip, etc.
//$clip['category'] = $webclip[$ad_cat]; // a number
// 1 = Gmail Tip, 2 = News, 3 = Business, 4 = Lifestyle
// 5 = Fun, 6 = Tech, 7 = Sports, 8 = custom
$clips[] = $clip;
}
$this->web_clips = $clips;
return 1;
}
}
/**
* Class Debugger
*
* @package GMailer
*/
class Debugger {
/**
* Record debugging message.
*
* @param string $str Message to be recorded
* @return void
* @static
*/
function say($str) {
global $D_FILE, $D_ON;
if ($D_ON) {
$fd = fopen($D_FILE, "a+");
$str = str_replace("*/", "*", $str); // plug possible security hole
fwrite($fd, "<?php /** ".$str." **/ ?".">\n");
fclose($fd);
}
}
}
define("GM_DEBUG_CURL", false); // Added by Neerav; 19 Apr 2006
?>