<?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; 5 Mar 2006
define("GM_USER_AGENT", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6");
/**
* @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);
/**#@-*/
/**#@+
* Other constants.
*/
define("GM_VER", "0.9 Beta 2");
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);
/**#@-*/
/**
* 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|no@spam|users.sourceforge.net>
* @author Neerav Modi <neeravmodi|no@spam|users.sourceforge.net>
* @link http://gmail-lite.sourceforge.net Project homepage
* @link http://sourceforge.net/projects/gmail-lite Sourceforge project page
* @version 0.8.0-rc
*/
class GMailer {
/**#@+
* @access private
* @var string
*/
var $cookie_str;
var $login;
var $pwd;
/**
* @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->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);
}
/**
* 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($this->proxy_host) > 0) {
$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;
}
}
}
if (!($method & GM_USE_COOKIE)) {
@ini_set("session.use_cookies", 0);
@ini_set("session.use_trans_sid", 1);
$a = array(
"action" => "session",
"status" => "success",
"message" => "no 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" => "session",
"status" => "success",
"message" => "using cookie"
);
array_unshift($this->return_status, $a);
}
@ini_set("arg_separator.output", '&');
session_start();
$a = array(
"action" => "session",
"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" => "session",
"status" => "success",
"message" => "using cookie"
);
array_unshift($this->return_status, $a);
$this->use_session = false;
}
}
/**
* @return binary image
* @desc
*/
/* 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_RETURNTRANSFER, 1); */
/* curl_setopt($c, CURLOPT_BINARYTRANSFER, 1); */
/* curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1); */
/* curl_setopt($c, CURLOPT_URL, "https://www.google.com/accounts/Captcha?ctoken=".urlencode($logintoken)."&email=".$login."@gmail.com"); */
/* curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); */
/* curl_setopt($c, CURLOPT_USERAGENT, GM_USER_AGENT); */
/* // curl_setopt($c, CURLOPT_COOKIE, $this->cookie_str); */
/* $this->CURL_PROXY($c); */
/* // curl_setopt($c, CURLOPT_HEADER, 1); */
/* curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE); */
/* curl_setopt($c, CURLOPT_REFERER, "https://www.google.com/accounts/ServiceLoginAuth"); */
/* $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 = "service=mail";
$postdata .= "&Email=".urlencode($this->login);
$postdata .= "&Passwd=".urlencode(str_replace(' ','+',$this->pwd));
$postdata .= "&null=Sign%20in";
$postdata .= "&continue=https%3A%2F%2Fmail.google.com%2Fmail%3F";
// Added by Neerav; 28 June 2005
$postdata .= "&rm=false"; // not required but appears
$postdata .= "&hl=en";
/* // Updated by Neerav; 4 Apr 2006 */
/* $postdata = array(); */
/* $postdata['ltempl'] = "yj_blanco"; */
/* $postdata['ltemplcache'] = 2; */
/* $postdata['continue'] = "http://mail.google.com/mail/"; */
/* $postdata['service'] = "mail"; */
/* $postdata['rm'] = "false"; */
/* $postdata['hl'] = "en"; */
/* $postdata['Email'] = $this->login; */
/* $postdata['Passwd'] = str_replace(' ','+',$this->pwd); */
/* $postdata['rmShown'] = 1; */
/* $postdata['null'] = "Sign in"; */
// Added by Neerav; 8 July 2005
// login challenge
//id="logintoken" value="cpVIYkaTDTkVZ9ZHNM_384GVV79tjExj-ac2NFVgS3AVbm7lEn7Q967JHKe_sDzMP7plluysBDJRyUwkjuHQFw:D0cwussDwRyIgJGSdeMMnA" name="logintoken">
if (isset($this->logintoken) and $this->logintoken != "") $postdata .= "&logintoken=".$logintoken;
if (isset($this->logincaptcha) and $this->logincaptcha != "") $postdata .= "&logincaptcha=".$logincaptcha;
$this->gmail_data = GMailer::execute_curl(GM_LNK_LOGIN, GM_LNK_LOGIN_REFER, 'post', $postdata, 'nocookie', "");
/* Debugger::say("first phase: ".print_r($this->gmail_data,true)); */
$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);
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)); */
/* print_r($cookies); */
$this->logintoken = "";
$this->logincaptcha = "";
if (strpos($this->gmail_data, "errormsg_0_Passwd") > 0) {
$this->cookie_str = "";
$this->cookie_ik_str = "";
// Added appropriate error message; by Neerav; 8 July 2005
$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);
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="cpVIYkaTDTkVZ9ZHNM_384GVV79tjExj-ac2NFVgS3AVbm7lEn7Q967JHKe_sDzMP7plluysBDJRyUwkjuHQFw:D0cwussDwRyIgJGSdeMMnA" 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_token_img" => urlencode("Captcha?ctoken=".$matches[1]."&email=".$this->login."%40gmail.com"),
//"login_token_img" => $login_img,
//"login_cookie" => $login_cookie,
"login_error" => "challenge"
);
array_unshift($this->return_status, $a);
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);
return false;
// Check for a cookie as a way to check the Gmail URL; Added by Neerav; 14 Sept 2005
} elseif ($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);
return false;
}
$a = array(
"action" => "phase one cookie",
"status" => "success",
"message" => "Received: ".$cookies
);
array_unshift($this->return_status, $a);
/*** js forward path (Gan: no longer used? 10 Sept 2005)
$a = strpos($this->gmail_data, "top.location = \"");
$b = strpos($this->gmail_data, ";", $a);
$forward = substr($this->gmail_data, $a+16, $b-($a+16)-1);
// forces relative url into absolute if not already; Added by Neerav; 31 July 2005
if (substr($forward,0,8) != "https://") {
$forward = "https://mail.google.com/accounts/".$forward;
}
**/
$a = strpos($this->gmail_data, "Location: ");
$b = strpos($this->gmail_data, "\n", $a);
$forward = substr($this->gmail_data, $a+10, $b-($a+10));
$a = array(
"action" => "redirecting",
"status" => "success",
"message" => "Redirecting to: ".$forward
);
array_unshift($this->return_status, $a);
// Forward url is now absolute instead of relative; Fixed by Gan; 27 July 2005
//curl_setopt($c, CURLOPT_URL, "https://mail.google.com/accounts/".$forward);
/* $ret = GMailer::execute_curl($forward, GM_LNK_REFER, 'post', $postdata, "cookie", $cookies); */
// Added extra required cookie; by Neerav; 4 Apr 2006
$second = GMailer::execute_curl($forward, GM_LNK_LOGIN_REFER, 'get', "", "cookie", "GoogleAccountsLocale_session=en; ".$cookies);
$data = GMailer::get_cookies($second);
/* Debugger::say("second phase: ".print_r($second,true)); */
/* Debugger::say("second phase cookies: ".print_r($data,true)); */
/* print_r($data); */
$a = array(
"action" => "phase two cookie",
"status" => "success",
"message" => "Obtained: ".$d
);
array_unshift($this->return_status, $a);
/* $this->cookie_str = $cookies.";".$d; // the cookie string obtained from gmail */
if (strpos($second, "SetSID") !== false) {
$a = array(
"action" => "phase three required",
"status" => "success",
"message" => "Starting..."
);
/* $forward = preg_match("/<meta content=\"0;\s*url=([^\"]*)\"/",$second,$matches); */
/* print_r($matches); */
/* Debugger::say("third phase location: ".print_r($matches,true)); */
/* $third = GMailer::execute_curl( */
/* str_replace("&","&",$forward[1]), */
/* "", // no referrer */
/* 'get', "", */
/* "nocookie", ""); */
$forward = preg_match("/<meta content=\"0;\s*url=([^\"]*)\"/",$second,$matches);
/* print_r($matches); */
/* Debugger::say("third phase location: ".print_r($matches,true)); */
/* print_r(str_replace("&","&",$matches[1])); */
$third = GMailer::execute_curl(
str_replace("&","&",$matches[1]),
"", // no referrer
'get', "",
"nocookie", "");
$data = GMailer::get_cookies($third);
/* Debugger::say("third phase: ".print_r($third,true)); */
/* Debugger::say("third phase cookies: ".print_r($data,true)); */
$data = preg_replace("/GX=.*?;\s?GX=/","GX=",$data);
/* Debugger::say("third phase cookies (corrected): ".print_r($data,true)); */
}
$d = ($data) ? $data : $cookies;
$d = $d.";TZ=".$this->timezone;
$this->cookie_str = preg_replace("/LSID=mail[^;]*?;/","",$d); // the cookie string obtained from gmail
/* print_r($this->cookie_str); */
// cleanup redundant cookies
/* $this->cookie_str = ereg_replace( */
/* "S=gmail=([^\:]*):gmail_yj=([^\:]*):gmproxy=([^\;]*);", */
/* "", */
/* $this->cookie_str */
/* ); */
/* $this->cookie_str .= ";S=gmail=".$matches[1].":gmail_yj=".$matches[2].":gmproxy=".$matches[3].";"; */
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") {
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(
GM_LNK_GMAIL."?".$query,
GM_LNK_REFER,
'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=".urlencode($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;
}
}
/**
* 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 $attid and message ID $msgid to file with name $filename.
*
* @return bool Success or not.
* @param string $attid Attachment ID.
* @param string $msgid Message ID.
* @param string $filename File name.
* @param bool $zipped Save all attachment of message ID $msgid into a zip file.
*/
function getAttachment($attid, $msgid, $filename, $zipped=false) {
if ($this->isConnected() == true) {
Debugger::say("Start getting attachment...");
if (!$zipped)
$query = GM_LNK_GMAIL."?view=att&disp=attd&attid=".urlencode($attid)."&th=".urlencode($msgid);
/* else */
/* $query = GM_LNK_GMAIL."?view=att&disp=zip&th=".urlencode($msgid); */
/* $query = GM_LNK_ATTACHMENT."&attid=".urlencode($attid)."&th=".urlencode($msgid); */
else
$query = GM_LNK_ATTACHMENT_ZIPPED."&th=".urlencode($msgid);
$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_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, GM_LNK_REFER);
curl_exec($c);
curl_close($c);
fclose($fp);
} 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;
}
}
/**
* 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(
GM_LNK_GMAIL."?".$query,
GM_LNK_REFER,
'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("who@what.com", "Hello World", "Cool!\r\nFirst mail!");
*
* // More than one recipients. And with CC:
* $gmailer->send("who@what.com, boss@company.com",
* "Hello World",
* "This is second mail.",
* "carbon-copy@company.com");
*
* // With file attachment
* $gmailer->send("who@what.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-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 your Gmail address (NOT the default one in your settings). 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";
$postdata["draft"] = $orig_df;
$postdata["rm"] = $mid;
$postdata["th"] = $tid;
} 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;
// Changed to add attachment/forward support ($getdata); by Neerav; 22 Oct 2005
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?&search=inbox&qt=&cmid=&newatt=".$new_attach."&rematt=0".$getdata,
/* GM_LNK_REFER, */
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.
* @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( */
/* GM_LNK_GMAIL."?".$link */
/* GM_LNK_GMAIL."?".$referrer, */
/* 'post', */
/* $postdata */
/* ); */
if ($this->isConnected()) {
$postdata = "";
$referrer = GM_LNK_REFER;
$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) {
$query = "&search=trash";
} elseif ($act == GM_ACT_DELSPAM) {
$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 = GM_LNK_GMAIL."?&search=cat&cat=".urlencode($mailbox)."&view=tl&start=0".$this->proxy_defeat();
}
} else {
$query = "&search=query&q=";
}
/* print(GM_LNK_GMAIL."?"."&qt=".$query."&view=up".$postdata.$this->proxy_defeat()); */
if ($act == GM_ACT_TRASHMSG || $act == GM_ACT_UNTRASHMSG || $act == GM_ACT_DELTRASHEDMSGS) {
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?"."&qt=".$query."&view=up".$postdata.$this->proxy_defeat(),
"",
'get'
);
} else {
$this->gmail_data = GMailer::execute_curl(
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])) {
$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])) {
$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.
*/
function saveSessionToBrowser() {
Debugger::say("Start saving session to server/browser...");
if ($this->isConnected()) {
if (!$this->use_session)
return $this->saveCookieToBrowser();
$_SESSION[GM_COOKIE_KEY] = base64_encode($this->cookie_str);
Debugger::say("Just saved session: ".GM_COOKIE_KEY."=".base64_encode($this->cookie_str));
Debugger::say("Completed saving session to server.");
return true;
}
Debugger::say("FAILED to save session to server/browser: not connected.");
return false;
}
/**
* @return bool Success or not.
* @desc Save (send) cookies to browser.
*/
function saveCookieToBrowser() {
Debugger::say("Start saving cookie to browser...");
if ($this->isConnected()) {
if (strpos($_SERVER["HTTP_HOST"],":"))
$domain = substr($_SERVER["HTTP_HOST"],0,strpos($_SERVER["HTTP_HOST"],":"));
else
$domain = $_SERVER["HTTP_HOST"];
Debugger::say("Saving cookies with domain=".$domain);
header("Set-Cookie: ".GM_COOKIE_KEY."=".base64_encode($this->cookie_str)."; Domain=".$domain.";");
//setcookie(GM_COOKIE_KEY, base64_encode($this->cookie_str), 1209600, "/" , $domain);
Debugger::say("Just saved cookie: ".GM_COOKIE_KEY."=".base64_encode($this->cookie_str));
Debugger::say("Completed saving cookie to browser.");
return true;
}
Debugger::say("FAILED to save cookie to browser: not connected.");
return false;
}
/**
* @return bool Success or not.
* @desc Remove all session information related to Gmailer.
*/
function removeSessionFromBrowser() {
Debugger::say("Start removing session from browser...");
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']);
Debugger::say("Cleared libgmailer related session info.");
Debugger::say("Session preserved for other use.");
} else {
// otherwise (normal) unset and destroy session
@session_unset();
@session_destroy();
Debugger::say("Just removed session: ".GM_COOKIE_KEY);
Debugger::say("Finished removing session from browser.");
}
return true;
}
/**
* @return bool
* @desc Remove all related cookies stored in browser.
*/
function removeCookieFromBrowser() {
Debugger::say("Start removing cookie from browser...");
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"];
Debugger::say("Removing cookies with domain=".$domain);
header("Set-Cookie: ".GM_COOKIE_KEY."=1; Discard; Max-Age=0; Domain=".$domain.";");
header("Set-Cookie: ".GM_COOKIE_IK_KEY."=0; Discard; Max-Age=0; Domain=".$domain.";");
Debugger::say("Just removed cookies: ".GM_COOKIE_KEY." and ".GM_COOKIE_IK_KEY);
return true;
} else {
Debugger::say("Cannot find libgmailer cookies: ".GM_COOKIE_KEY." or ".GM_COOKIE_IK_KEY);
return false;
}
} else {
Debugger::say("Cannot find any cookie from browser.");
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(
GM_LNK_GMAIL."?logout&hl=en".$this->proxy_defeat("nodash"),
//http://mail.google.com/mail/?&ik=&search=inbox&view=tl&start=0&init=1&zx=csp670w0j1ar
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);
// Updated by Neerav; 28 June 2005
//curl_setopt($c, CURLOPT_URL, GM_LNK_LOGOUT);
//curl_setopt($c, CURLOPT_URL, GM_LNK_GMAIL."?logout&hl=en&zx=".$this->proxy_defeat());
// "&ik=&" + this.Threads.LastSearch + "&view=tl&start=0&init=1&zx=" + this.MakeUniqueUrl();
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) {
if ($this->isConnected()) {
$postdata = "act=ii&em=".urlencode($email);
$postdata .= "&at=".$this->at_value();
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?view=ii",
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" => "$action label",
"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) {
$match = "";
preg_match_all('!Set-Cookie: ([^;\s]+)($|;)!', $header, $match);
/* Debugger::say("header: ".print_r($header,true)."\n\ncookies: ".print_r($match,true)); */
$cookie = "";
foreach ($match[1] as $val) {
if ($val{0} == '=') continue;
// Skip over "expired cookies which were causing problems; by Neerav; 4 Apr 2006
if ((strpos($val,"EXPIRED") !== false) or (strpos($val,"GoogleAccountsLocale_session") !== false)) continue;
$cookie .= $val . "; ";
}
return substr($cookie, 0, -2);
}
/**
* 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",
* "john@company.com",
* "Supervisor of project X",
* "");
*
* // Add a new one with lots of details
* $gmailer->editContact(
* -1,
* "Mike G. Stone",
* "mike@company.com",
* array(
* array(
* "phone" => "123-45678",
* "mobile" => "987-65432",
* "fax" => "111-11111",
* "pager" => "222-22222",
* "im" => "34343434",
* "company" => "22nd Century Fox",
* "position" => "CEO",
* "other" => "Great football player!",
* "address" => "1 Fox Rd",
* "detail_name" => "Work"
* ),
* array(
* "phone" => "1-23-4567",
* "mobile" => "9-87-6543",
* "email" => "mike.at.home@home.net",
* "im" => "stonymike (yahoo)",
* "im" => "stonymike@hotmail.com",
* "other" => "Has huge collection of World Cup t-shirts",
* "address" => "1 Elm Street",
* "detail_name" => "Home"
* )
* );
*
* // Modified an existing one
* $gmailer->editContact($contact_id,
* "Old Name",
* "new_mail@company.com",
* "Old notes"
* );
* ? >
* </code>
*
* Note: You must supply the old name even if you are not going to modify it, or it will
* be changed to empty!
*
* @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 $detail) {
$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();
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?view=up",
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];
}
/* Debugger::say((($orig_contact_id == -1) ? "add contact": "edit contact").": ".print_r($this->gmail_data,true)); */
$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, 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, 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)) {
//URL: POST /gmail/?&ik=&view=up HTTP/1.1
//Referer: http://mail.google.com/mail/?&ik=xxx&view=cl&search=contacts&pnl=a&zx=zfowhxlm2nrh
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?view=up",
GM_LNK_GMAIL."?view=cl&search=contacts&pnl=a",
'post',
$query
);
} else {
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?".$query,
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", "delete" 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 = array();
if ($action == "create") {
$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" => (($status) ? "success" : "failed"),
"message" => "libgmailer error: unknown action in editLabel()"
);
array_unshift($this->return_status, $a);
return false;
}
$postdata["at"] = $this->at_value();
//Debugger::say(GM_LNK_GMAIL_HTTP."?&ik=".$_SESSION['id_key']."&view=pr&pnl=l".$this->proxy_defeat());
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL_HTTP."?&ik=&view=up",
GM_LNK_GMAIL_HTTP."?&ik=".$_SESSION['id_key']."&view=pr&pnl=l".$this->proxy_defeat(),
'post',
$postdata
);
GMailer::parse_gmail_response($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) {
$action = ($filter_id == 0) ? "create" : "edit";
if ($this->isConnected()) {
$query = "";
$query .= "view=pr";
$query .= "&pnl=f";
$query .= "&at=".$this->at_value();
if ($action == "create") {
// create new filter
$query .= "&act=cf";
$query .= "&cf_t=cf";
} 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);
$query .= "&cf2_emc=" ; $query .= ($forward == true) ? "true" : "false" ;
$query .= "&cf2_email=" . urlencode($forwardto);
$query .= "&cf2_tr=" ; $query .= ($trash == true) ? "true" : "false" ;
if ($action == "edit") {
$query .= "&ofid=".$filter_id;
}
$query .= $this->proxy_defeat(); // to fool proxy
$refer = "";
$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="; $query .= ($hasAttach == true) ? "true" : "false" ;
if ($action == "edit") {
$refer .= "&cf2_ar=" ; $query .= ($archive == true) ? "true" : "false" ;
$refer .= "&cf2_st=" ; $query .= ($star == true) ? "true" : "false" ;
$refer .= "&cf2_cat=" ; $query .= ($label == true) ? "true" : "false" ;
$refer .= "&cf2_sel=" . urlencode($label_name);
$refer .= "&cf2_emc=" ; $query .= ($forward == true) ? "true" : "false" ;
$refer .= "&cf2_email=" . urlencode($forwardto);
$refer .= "&cf2_tr=" ; $query .= ($trash == true) ? "true" : "false" ;
$refer .= "&ofid=" . urlencode($filter_id);
}
$refer .= $this->proxy_defeat(); // to fool proxy
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?".$query,
GM_LNK_GMAIL."?".$refer,
'get'
);
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" => "$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;
}
}
/**
* 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 = "";
//PostData = "act=df_" + this.id.ToString() +
//"&at=" + this.Parent.Cookies["GMAIL_AT"].Value;
$query .= "act=df_".$id;
$query .= "&at=".$this->at_value();
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL."?ik=&view=up",
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)
* @author Neerav
* @since 10 Jan 2006
*/
function editGroup($id,$name,$action,$data = "") {
if ($this->isConnected()) {
if ($action == "rename") {
$refer = GM_LNK_GMAIL."?search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
$query['act'] = "rcl_".$id."^".$data;
$query['at'] = $this->at_value();
$query['cpt'] = "cpta";
$query['cl_id'] = $id;
$query['cl_nm'] = $name;
} elseif ($action == "delete") {
$refer = GM_LNK_GMAIL."?view=cl&search=contacts&pnl=l".$this->proxy_defeat();
$query['act'] = "dcal";
$query['at'] = $this->at_value();
$query['cpt'] = "";
$query['cl_nw'] = "";
$query['cl_id'] = "";
$query['cl_nm'] = "";
$query['cl'] = $id;
} elseif ($action == "create") {
$refer = GM_LNK_GMAIL."?view=nctl&search=contacts".$this->proxy_defeat();
$query['act'] = "ancl"; // add new contact list
$query['at'] = $this->at_value();
$query['cl_nm'] = $name;
$query['ce'] = (is_array($data)) ? implode(", ",$data) : $data;
} elseif ($action == "remove_from") {
$refer = GM_LNK_GMAIL."?search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
$query = "&act=rfcl"; // remove from contact list
$query .= "&at=".$this->at_value();
$query .= "&cpt=cpta";
$query .= "&cl_id=".$id;
$query .= "&cl_nm=".$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 = GM_LNK_GMAIL."?&search=contacts&ct_id=".$id."&cvm=1&view=ctl".$this->proxy_defeat();
$query['act'] = "atcl"; // add to contact list
$query['at'] = $this->at_value();
$query['cpt'] = "cpta";
$query['cl_id'] = $id;
$query['cl_nm'] = $name;
$query['ce'] = implode(", ",$data);
} 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(
GM_LNK_GMAIL."?ik=&view=up",
$refer,
'post',
$query
);
GMailer::parse_gmail_response($this->gmail_data);
$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
);
array_unshift($this->return_status, $a);
return $status;
} else {
$a = array(
"action" => $action." contact group",
"status" => "failed",
"message" => "libgmailer: not connected"
);
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 $chat_archive Save chat scripts
* @param bool $aa_unknown ??
* @author Neerav
* @since 29 Jun 2005
*/
function setSetting(
//$use_outgoing_name, $outgoing_name, $use_reply_email, $reply_to,
$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
) {
/*
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}
// 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 = 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}
"bx_aa" // ??
// Chat
"ix_ca" // (boolean) save chat archives? {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=10"; */
/* $query .= "&bx_lq=0"; */
/* $query .= "&bx_aa=1"; */
$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'] =1; */
/* $post_fields['p_ix_ql'] =10; */
/* $post_fields['p_bx_lq'] =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";
} else {
$post_fields['dp'] = "bx_vc";
}
//$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(
GM_LNK_GMAIL."?".$post_url,
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 = "") {
$message = '';
if ($method != "get" and $method != "post") {
$message = 'The cURL method is invalid.';
}
if ($url == "") {
$message = 'The cURL url is blank.';
}
/* if ($referrer == "") { */
/* $message = 'The cURL referrer is blank.'; */
/* } */
/* if ($method == "post" and (!is_array($data) or count($data) == 0)) { */
/* $message = 'The cURL post data for POST is empty or invalid.'; */
/* } */
// error
if ($message != '') {
array_unshift($this->return_status, array("action" => "execute cURL", "status" => "failed", "message" => $message));
return;
}
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 ($extra_type == "nocookie") { */
/* curl_setopt($c, CURLOPT_FOLLOWLOCATION, 0); */
/* } else { */
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
/* } */
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));
}
/* curl_setopt($c, CURLOPT_COOKIE, $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") {
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 0);
} else {
curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
}
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);
/* // debugging cURL */
/* $fd = fopen("debug_curl.txt", "a+"); */
/* curl_setopt($c, CURLOPT_VERBOSE, 1); */
/* curl_setopt($c, CURLOPT_STDERR, $open_file_handle); */
$gmail_response = curl_exec($c);
curl_close($c);
/* // close debugging file */
/* fclose($fd); */
return $gmail_response;
}
/**
* 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()) {
$post = array();
$get = "";
$post['nvp_bu_done'] = "Save";
$get .= "nvp_bu_done=Save";
$post_url = "x/".$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] != "") {
/* $post['cfvc_'.$i] = urlencode($mobile_display[$i]); */
$post['cfvc_'.$i] = $mobile_display[$i];
$get .= "&cfvc_".$i."=".urlencode($mobile_display[$i]);
}
}
$this->gmail_data = GMailer::execute_curl(
GM_LNK_GMAIL_HTTP.$post_url,
GM_LNK_GMAIL_HTTP."x/".$this->proxy_defeat("nodash")."-/?v=cmf",
'post',
/* $post */
$get
);
/* print_r($post); */
/* Debugger::say("gmail response when setting mobile prefs: ".print_r($this->gmail_data,true)); */
$status = (strstr($this->gmail_data,'<a href="?v=cmf">more views</a>') === 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(
GM_LNK_GMAIL."?".$query,
GM_LNK_GMAIL."?".$refer,
'get'
);
//S=gmail=j8lv94EXSjI:gmail_yj=Fs3UajIqvjY:gmproxy=ZwcQ86EuvyY;
ereg("S=gmail=([^\:]*):gmail_yj=([^\:]*):gmproxy=([^\;]*);",$this->gmail_data,$matches);
/* //Debugger::say("cookie matches: ".print_r($matches,true)); */
$this->cookie_str = ereg_replace(
"S=gmail=([^\:]*):gmail_yj=([^\:]*):gmproxy=([^\;]*);",
"S=gmail=".$matches[1].":gmail_yj=".$matches[2].":gmproxy=".$matches[3].";",
$this->cookie_str
);
/* //Debugger::say("new cookie: ".print_r($this->cookie_str,true)); */
// save updated cookie
GMailer::saveSessionToBrowser();
// 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":
$postdata = "act=mcf_".urlencode($email);
$postdata .= "&at=".$this->at_value();
break;
case "delete":
$postdata = "act=dcf_".urlencode($email);
$postdata .= "&at=".$this->at_value();
break;
case "reply_sent":
$postdata = "act=crf_1";
$postdata .= "&at=".$this->at_value();
$postdata .= "&search=";
break;
case "reply_default":
$postdata = "act=crf_0";
$postdata .= "&at=".$this->at_value();
$postdata .= "&search=";
break;
case "edit":
$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":
$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": */
/* $postdata = ""; */
/* $url = "&view=cf".$this->proxy_defeat(); */
/* $method = 'get'; */
/* break; */
/* case "add": */
/* $postdata = array(); */
/* $postdata['cfrp'] = 1; */
/* $postdata['cfn'] = $name; */
/* $postdata['cfa'] = $email; */
/* $postdata['cfrt'] = $reply_to; */
/* $url = "&view=cf"; */
/* $refer = $url; */
/* break; */
case "send_verify":
$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":
$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(
GM_LNK_GMAIL."?".$url,
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;
}
}
/**
* Parse Gmail responses.
*
* @access private
* @static
* @return bool
* @param string $raw_html
* @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) {
$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
$raw_html = str_replace(array('u003d','u002f'),array('=','/'),$raw_html);
/* $raw_html = preg_replace(array('/(<[^>]*?u003d[^>]*?'.'>)/e'),array('str_replace("u003d","=",\1)'),$raw_html); */
/* $raw_html = str_replace(array('\\\\u003d\\\\','\\\\u002f\\\\'),array('=','/'),$raw_html); */
/* $raw_html = preg_replace(array('/(<[^>]*?u003d[^>]*?'.'>)/e'),array('str_replace("u003d","=",\1)'),$raw_html); */
/* $raw_html = preg_replace('/(\w)u003d\"/','\\1=\\2',&$raw_html); */
/* $raw_html = str_replace(array('u003d\"','u002f'),array('=\"','/'),$raw_html); */
/* $raw_html = preg_replace(array('/(<[^>]*?)u003d/'),array('\\1='),$raw_html); */
$regexp = "|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()} 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=') !== 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.";");
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"
// Added by Neerav; 6 July 2005
if (isset($raw["ud"])) {
// account email address
// your app SHOULD cache this in session or cookie for use across pages
// Added by Neerav; 6 May 2005
$this->gmail_email = $raw["ud"][1];
//$raw["ud"][2] // keyboard shortcuts
//$raw["ud"][3] // Identification Key, set above
//$raw["ud"][4] // What is this? referrer?
//$raw["ud"][5] // What is this?
//$raw["ud"][6] // What is this?
//$raw["ud"][7] // What is this?
}
// su
//$raw["su"][1] // What is this? (matches $raw["v"][2])
//$raw["su"][2] // What is this? (?? array of text strings for invites)
// cp
//$raw["cp"][1] // What is this? (always 1)
//$raw["cp"][2] // What is this? (always 0)
// csm
//$raw["csm"][1] // What is this? (always 1)
// cld
//$raw["cld"] // What is this? (empty)
// COUntry
// Added by Neerav; 20 Dec 2005
$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])) {
$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
);
}
}
}
// What is this?
// $raw["df"][1] // shows ?false?
// $raw["ms"]
// $raw["e"]
// $raw["pod"]
// $raw["te"]
// $raw["csm"][1]
// $raw["ad"] // web clips and advertisements
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"])) {
$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();
// 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));
}
// Thread 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?
//$this->?? = $raw["ts"][9]; // what is this?? serial number, id number, VERY LONG!
//$this->?? = $raw["ts"][10]; // what is this?? always blank
}
$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);
}
}
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 = (count($raw["cs"]) == 12) ? 2 : 0 ;
$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] // may be 9 what is this?? repeat of id 1?
// $raw["cs"][12-$less] // may be 10 what is this?? array
// $raw["cs"][13-$less] // may be 11 what is this?? integer/bool?
$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])) {
$b["body"] .= $raw["mg"][$i][1];
} else {
// Added error; by Neerav; 9 Feb 2006
// THIS ERROR OCCURS BECAUSE ??
$this->snapshot_error = "libg101";
$this->created = 0;
return null;
}
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["recv"] = strip_tags($raw["mg"][$i][9]);
$b["recv_email"] = str_replace("\"", "", $raw["mg"][$i][11]);
$b["cc_email"] = str_replace("\"", "", $raw["mg"][$i][12]); // was only defined in draft, now both; Changed by Neerav; 11 July
$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][17])
) {
$b["bcc_email"] = str_replace("\"", "", $raw["mg"][$i][13]); // was only defined in draft, now both; Changed by Neerav; 11 July 2005
$b["reply_email"] = str_replace("\"", "", $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) {
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] // repeat of [0]?, what is this??
)
);
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") {
$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
// $raw["mg"][$i][23+$more]; // What is this?? sender's domain?
// $raw["mg"][$i][24+$more]; // always blank What is this??
// $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??
} elseif ($raw["mg"][$i][0] == "di") {
$b["is_draft"] = true;
$b["body"] = $raw["mg"][$i][20];
// $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" => "libgmailer@error.nonexistant",
"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
);
// 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" <email@address.net>, "Name2" <email2@address.net>, 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["notes"] = ""; // no notes for groups... yet!
$group_addresses = array(); // string of flattened email addresses
$group_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["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]) : "")
);
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,
);
// FORWARDING AND POP
$fpop = array(
"forward" => 0,
"forward_to" => "",
"forward_action"=> "selected",
"pop_enabled" => 0,
"pop_action" => 0
);
// 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
);
// 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];
}
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
// 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; 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
case "ix_ql": $chat["ix_ql"] = $value; break; // (integer)
case "bx_aa": $chat["bx_aa"] = $value; break; // (boolean)
case "bx_lq": $chat["bx_lq"] = $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
$this->label_list = array();
$this->label_total = array();
if (isset($raw["cta"][1])) {
foreach ($raw["cta"][1] as $v) {
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;
}
}
/**
* 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); // possible security hole
fwrite($fd, "<?php /** ".$str." **/ ?".">\n");
fclose($fd);
}
}
}
?>
|