diff --git a/checkin_notes b/checkin_notes
index 4a2a624e8e..aa55c656ba 100755
--- a/checkin_notes
+++ b/checkin_notes
@@ -5368,3 +5368,19 @@ David 27 May 2007
sg_ProjectsComponent.cpp
sg_ViewTabPage.cpp
DlgAdvPreferences Base.cpp
+
+Rytis 27 May 2007
+ - Donations system (running via PayPal).
+ NOTE: DB updated needed. Documented in
+ http://boinc.berkeley.edu/trac/wiki/PayPalDonations
+
+ db/
+ schema.sql
+ html/user/
+ currency.js
+ donate.php
+ donated.php
+ donation_ipn.php
+ donations.php
+ img/
+ paypal_logo.png
diff --git a/db/schema.sql b/db/schema.sql
index d588db3822..93819c0688 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -470,3 +470,33 @@ create table credited_job (
userid integer not null,
workunitid bigint not null
) TYPE=MyISAM;
+
+create table donation_items (
+ id integer unsigned not null auto_increment,
+ item_name varchar(32) not null,
+ title varchar(255) not null,
+ description varchar(255) not null,
+ required double unsigned not null default '0',
+ PRIMARY KEY(id)
+) TYPE=MyISAM;
+
+create table donation_paypal (
+ id integer not null auto_increment,
+ order_time integer unsigned not null,
+ userid integer not null,
+ email_addr varchar(255) not null,
+ order_amount double(6,2) not null,
+ processed tinyint(1) not null default '0',
+ payment_time integer unsigned not null,
+ item_name varchar(255) not null,
+ item_number varchar(255) not null,
+ payment_status varchar(255) not null,
+ payment_amount double(6,2) not null,
+ payment_fee double(5,2) default null,
+ payment_currency varchar(255) not null,
+ txn_id varchar(255) not null,
+ receiver_email varchar(255) not null,
+ payer_email varchar(255) not null,
+ payer_name varchar(255) not null,
+ PRIMARY KEY(id)
+) TYPE=MyISAM;
\ No newline at end of file
diff --git a/html/ops/db_update.php b/html/ops/db_update.php
index ddd66e3ca0..8c2c19ed2f 100755
--- a/html/ops/db_update.php
+++ b/html/ops/db_update.php
@@ -391,11 +391,42 @@ function update_4_30_2007() {
);
}
+function update_5_27_2007() {
+ do_query("create table donation_items (
+ id integer unsigned not null auto_increment,
+ item_name varchar(32) not null,
+ title varchar(255) not null,
+ description varchar(255) not null,
+ required double unsigned not null default '0',
+ PRIMARY KEY(id)
+) TYPE=MyISAM;");
+ do_query("create table donation_paypal (
+ id integer not null auto_increment,
+ order_time integer unsigned not null,
+ userid integer not null,
+ email_addr varchar(255) not null,
+ order_amount double(6,2) not null,
+ processed tinyint(1) not null default '0',
+ payment_time integer unsigned not null,
+ item_name varchar(255) not null,
+ item_number varchar(255) not null,
+ payment_status varchar(255) not null,
+ payment_amount double(6,2) not null,
+ payment_fee double(5,2) default null,
+ payment_currency varchar(255) not null,
+ txn_id varchar(255) not null,
+ receiver_email varchar(255) not null,
+ payer_email varchar(255) not null,
+ payer_name varchar(255) not null,
+ PRIMARY KEY(id)
+) TYPE=MyISAM;");
+}
+
// modify the following to call the function you want.
// Make sure you do all needed functions, in order.
// (Look at your DB structure using "explain" queries to see
// which ones you need).
-//update_4_30_2007();
+//update_5_27_2007();
?>
diff --git a/html/user/currency.js b/html/user/currency.js
new file mode 100644
index 0000000000..ac3820b8e8
--- /dev/null
+++ b/html/user/currency.js
@@ -0,0 +1,95 @@
+// From gocurrency
+
+var currency = new Array("TRY","AFA","DZD","USD","AOA","ANG","ARS","AMD","AWG","AUD","AZM","XOF","XAF","BSD","BBD","BYR","BZD","BMD","BTN","BOB","BAM","BWP","BRL","GBP","BND","BGN","BIF","XPF","KHR","CAD","KYD","CLP","CNY","COP","KMF","CDF","CRC","HRK","CUP","CYP","CZK","DKK","DJF","DOP","XCD","EGP","SVC","ERN","EEK","ETB","EUR","FKP","FJD","GMD","GEL","GHC","GIP","GTQ","GNF","GYD","HTG","HNL","HKD","HUF","IRR","ISK","INR","IDR","IQD","ILS","JMD","JPY","JOD","KZT","KES","KGS","KWD","LAK","LVL","LBP","LSL","LRD","LYD","LTL","MOP","MKD","MGA","MWK","MYR","MVR","MTL","MRO","MUR","MXN","MDL","MNT","MAD","MZM","MMK","NAD","NPR","NZD","NIO","NGN","KPW","NOK","OMR","PKR","PAB","PGK","PYG","PEN","PHP","PLN","CVE","QAR","ROL","RUB","RWF","SHP","STD","SAR","CSD","SCR","SLL","SGD","SKK","SIT","SBD","SOS","WST","ZAR","KRW","LKR","SDD","SRD","SZL","SEK","CHF","SYP","TWD","TZS","THB","TOP","TTD","TND","TRL","TMM","UGX","UAH","UYU","AED","UZS","VUV","VEB","VND","YER","ZMK","ZWD");
+var country = new Array("","AF","DZ","US","AO","AN","AR","AM","AW","AU","AZ","XO","XA","BS","BB","BY","BZ","BM","BT","BO","BA","BW","BR","GB","BN","BG","BI","XP","KH","CA","KY","CL","CN","CO","KM","CD","CR","HR","CU","CY","CZ","DK","DJ","DO","XC","EG","SV","ER","EE","ET","EU","FK","FJ","GM","GE","GH","GI","GT","GN","GY","HT","HN","HK","HU","IR","IS","IN","ID","IQ","IL","JM","JP","JO","KZ","KE","KG","KW","LA","LV","LB","LS","LR","LY","LT","MO","MK","MG","MW","MY","MV","MT","MR","MU","MX","MD","MN","MA","MZ","MM","NA","NP","NZ","NI","NG","KP","NO","OM","PK","PA","PG","PY","PE","PH","PL","CV","QA","RO","RU","RW","SH","ST","SA","CS","SC","SL","SG","SK","SI","SB","SO","WS","ZA","KR","LK","SD","SR","SZ","SE","CH","SY","TW","TZ","TH","TO","TT","TN","TR","TM","UG","UA","UY","AE","UZ","VU","VE","VN","YE","ZM","ZW");
+var rate = new Array("","43","72.12","1","80.1823","1.78","3.0375","447","1.79","1.34084","4588","528.13","527.06","1","0.37697","1.99","2149.35","1.96","0.98","44.7","7.95","1.5811","5.40541","2.129","0.55944","1.588","1.5727","976","96.2","4005","1.1314","0.82","516.25","8.0095","2352","397.75","425","506.76","5.878","1","0.4633","22.842","5.9995","175.15","32.3","2.67","5.7498","1","13.5","12.6076","8.6896","0.80425","0.62688","1.75439","27.9","1.8098","9100","0.55975","7.572","4450","190","40.9","18.895","7.7531","212.16","9130","74.59","44.88","8805","1469.2","4.5245","62","114.81","0.7085","124.12","71.25","40.9126","0.29201","9950","0.5595","1501","5.95","54","1.3265","2.7767","8.0061","49.47","2175","137.85","3.6415","12.6","0.34594","263.49","30.62","11.1495","12.99","1192","8.8699","26900","6.42","6.0635","71.65","1.60051","17.11","127.5","143.05","6.3052","0.38498","59.95","1","3.08928","5730","3.315","51.83","3.1174","89.3","3.6398","29766","27.402","549.98","0.55975","6940","3.7504","69.73","5.1975","2350","1.5872","29.894","192.65","7.57576","1440","2.89855","6.075","945","102.64","223.5","2.71","6.039","7.4922","1.2674","51.91","31.943","1210","37.63","2.03252","6.269","1.3284","1.325","1345000","5200","1824","5.04","23.95","3.6727","1220.94","111.1","2144.6","15936","196.25","3080","99201.6");
+
+var fromFlag = new Array(3,23,9,50,125,71); var nVal = 1;
+var toFlag = new Array(50,23,71,66,9,125);
+
+function numberFormat() {
+ var fltNum = document.calcForm.outV.value;
+ var intNum = document.calcForm.outV.value;
+ intNum = intNum.replace(',','');
+ intNum = parseFloat(intNum);
+ if(fltNum.indexOf('.') > 0 )
+ {
+ var dec = fltNum.substr(fltNum.indexOf('.')+1,2);
+ dec = parseInt(dec);
+ if(dec < 10)
+ dec = dec * 10;
+ } else {
+ var dec = "00";
+ }
+ document.calcForm.outV.value = intNum;
+}
+
+function Cvalue()
+{
+ var fromR, toR, resultV;
+ fromR = rate[parseInt(document.calcForm.from.value)];
+ toR = rate[document.calcForm.to.selectedIndex];
+ nVal = document.calcForm.inV.value;
+
+ if ( IsNumeric(nVal) == false ) {
+ alert("amount to multiply is not a number\n\nyou can only use\n\n1234567890 and . (dot)");
+ }
+
+ resultV = nVal * ( toR / fromR );
+
+ // 6 relevant digits only, or integer
+ if ( (resultV == parseInt(resultV)) || (resultV > 99999) )
+ {
+ // mostly integer
+ resultV = parseInt( resultV );
+ }
+ else
+ {
+ if (resultV > 1)
+ {
+ resultV = resultV.toString();
+ resultV = resultV.substring(0,7);
+ } else {
+ resultV = resultV.toString();
+ resultV = resultV.substring(0,8);
+ }
+ }
+
+
+ document.calcForm.outV.value = " " + comma(resultV) + " " + currency[document.calcForm.to.selectedIndex];
+}
+
+function comma(num)
+{
+ var n = Math.floor(num);
+ var myNum = num + "";
+ var myDec = ""
+
+ if (myNum.indexOf('.',0) > -1){
+ myDec = myNum.substring(myNum.indexOf('.',0),myNum.length);
+ }
+ var arr=new Array('0'), i=0;
+ while (n>0)
+ {arr[i]=''+n%1000; n=Math.floor(n/1000); i++;}
+ arr=arr.reverse();
+ for (var i in arr) if (i>0) //padding zeros
+ while (arr[i].length<3) arr[i]='0'+arr[i];
+ return arr.join() + myDec;
+}
+
+function IsNumeric(strString)
+{
+ var strValidChars = "0123456789.";
+ var strChar;
+ var blnResult = true;
+
+ for (i = 0; i < strString.length && blnResult == true; i++)
+ {
+ strChar = strString.charAt(i);
+ if (strValidChars.indexOf(strChar) == -1)
+ {
+ blnResult = false;
+ }
+ }
+ return blnResult;
+}
diff --git a/html/user/donate.php b/html/user/donate.php
new file mode 100644
index 0000000000..222cd8e93b
--- /dev/null
+++ b/html/user/donate.php
@@ -0,0 +1,37 @@
+id;
+}
+
+$order_time = time();
+
+// Write user id to paypal table, so the return script knows it's expecting this payment
+$sql = "INSERT INTO donation_paypal SET order_time = '".$order_time."', userid = '$userid', item_number=".$item_id.", order_amount = '$amount'";
+mysql_query($sql);
+
+$payment_id = mysql_insert_id();
+
+$URL = "www.paypal.com/cgi-bin/webscr";
+
+$fields = ("cmd=_xclick&lc=US&business=".PAYPAL_ADDRESS."&quantity=1&item_name=Donation&item_number=".$payment_id."_".$order_time."&amount=".$amount."&no_shipping=1&return=".URL_BASE."donated.php&rm=2&cancel_return=".URL_BASE."donated.php&no_note=1¤cy_code=".$currency."&bn=PP-BuyNowBF");
+
+header("Location: http://$URL?$fields");
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/html/user/donated.php b/html/user/donated.php
new file mode 100644
index 0000000000..253b01b722
--- /dev/null
+++ b/html/user/donated.php
@@ -0,0 +1,17 @@
+Thank you for donating!
\n";
+ echo "Your donation for has been completed.
\n";
+ echo "Your donation will be added to the progress bar after confirmation by PayPal.";
+} else {
+ echo "You have canceled your donation";
+}
+
+page_tail();
+
+?>
diff --git a/html/user/donation_ipn.php b/html/user/donation_ipn.php
new file mode 100644
index 0000000000..e070320ede
--- /dev/null
+++ b/html/user/donation_ipn.php
@@ -0,0 +1,60 @@
+ $value) {
+ $value = urlencode(stripslashes($value));
+ $req .= "&$key=$value";
+}
+
+// post back to PayPal system to validate
+$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
+$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
+$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
+$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
+
+// assign posted variables to local variables
+$item_name = $_POST['item_name'];
+$item_number = $_POST['item_number'];
+$payment_status = $_POST['payment_status'];
+$payment_amount = $_POST['mc_gross'];
+$payment_fee = $_POST['mc_fee'];
+$payment_currency = $_POST['mc_currency'];
+$txn_id = $_POST['txn_id'];
+$receiver_email = $_POST['receiver_email'];
+$payer_email = $_POST['payer_email'];
+$payer_name = $_POST['first_name']." ".$_POST['last_name'];
+$ip = $_SERVER['REMOTE_ADDR'];
+$agent = strtolower($_SERVER[HTTP_USER_AGENT]);
+
+if (!$fp) {
+ // HTTP ERROR, might want to do additional handling here
+} else {
+ fputs ($fp, $header . $req);
+ while (!feof($fp)) {
+ $res = fgets ($fp, 1024);
+ if (strcmp ($res, "VERIFIED") == 0) {
+ $item_array = explode("_",$item_number);
+ $payment_id = abs($item_array[0]);
+ $order_time = abs($item_array[1]);
+ $sql = "SELECT * FROM donation_paypal WHERE order_time = '$order_time' AND id = '$payment_id' AND processed = '0'";
+ $result = mysql_query($sql,$db);
+ $num_rows = mysql_num_rows($result);
+ if ($num_rows == 1) {
+ $row = mysql_fetch_object($result);
+ $userid = $row->userid;
+ mysql_query("UPDATE donation_paypal SET processed = '1', payment_time = '".time()."', item_name = '$item_name', item_number = '$item_number', payment_status = '$payment_status', payment_amount = '$payment_amount', payment_fee = '$payment_fee', payment_currency = '$payment_currency', txn_id = '$txn_id', receiver_email = '$receiver_email', payer_email = '$payer_email', payer_name = '$payer_name' WHERE id = '$payment_id'");
+ if ($userid > 0) {
+ mysql_query("UPDATE user SET donated = '1' WHERE id = '$userid'");
+ }
+ }
+ }
+ }
+ fclose ($fp);
+}
+
+?>
diff --git a/html/user/donations.php b/html/user/donations.php
new file mode 100644
index 0000000000..3f5c779ae8
--- /dev/null
+++ b/html/user/donations.php
@@ -0,0 +1,307 @@
+id;
+}
+
+page_head(PROJECT." donations");
+
+if (function_exists("donations_intro")) {
+ donations_intro();
+} else {
+ echo "