I use the PayPal SDK for PHP and want to go to the checkout without showing details and total instead of subtotal (like on the picture left).
Thanks!
Example Picture
This is the Code i use.
$arrPrices = $this->getPrices();
$apiContext = $this->getApiContext();
$payer = new \PayPal\Api\Payer();
$payer->setPaymentMethod("paypal");
$arrItems = [];
$item = new \PayPal\Api\Item();
$item->setName($saveValues['title'])->setCurrency('EUR')->setQuantity(1)->setPrice($arrPrices['raw']);
$arrItems[] = $item;
$itemList = new \PayPal\Api\ItemList();
$itemList->setItems($arrItems);
$details = new \PayPal\Api\Details();
$details->setTax($arrPrices['tax'])->setSubtotal($arrPrices['raw']);
$amount = new \PayPal\Api\Amount();
$amount->setCurrency("EUR")->setTotal($arrPrices['total'])->setDetails($details);
$transaction = new \PayPal\Api\Transaction();
$transaction->setAmount($amount)->setItemList($itemList)->setDescription("Vielen Dank für Deine Buchung & bis bald!");
$redirectUrls = new \PayPal\Api\RedirectUrls();
$url = \Environment::get('url') . '/' . $GLOBALS['SCRIPT_URL'];
$redirectUrls->setReturnUrl("$url?success=true")->setCancelUrl("$url?success=false");
$payment = new \PayPal\Api\Payment();
$payment->setIntent("sale")->setPayer($payer)->setRedirectUrls($redirectUrls)->addTransaction($transaction);
try {
$payment->create($apiContext);
}
catch (\Exception $ex) {
return $ex->getData();
}
return $payment->getApprovalLink();
If you don't provide the details you will not see the details ? there isn't a way by which you will provide the details and then not have display it on the paypal approval page (of which you are showing the screen shot)
We are using billing agreement with rest api and we are able to successfully do it on sandbox.
Now we have requirement of discount on first month,
so if the have an agreement of 100$ for every month and when user applies some referral coupon, he will get 10$ discount on 1st month .i.e he should be charge 90$ on 1st month and 100$ going forward in the agreement period.
I couldn't see any option other than setup fee, but this can only be used for additional fee, i.e to increase the plan amount but not some thing less.
You must use paypal express checkout api to do this.
From paypal api documentation - https://developer.paypal.com/docs/classic/express-checkout/ht_ec-freeTrialRecurringPayments-curl-etc/
Using api method CreateRecurringPaymentsProfile you can change:
RIALBILLINGPERIOD: Period of time in one trial period. For example, a month.
TRIALBILLINGFREQUENCY: Frequency of charges, if any, in a period.
TRIALBILLINGFREQUENCY: Frequency of charges, if any, in a period.
TRIALTOTALBILLINGCYCLES: Trial period's length. That is, the number of periods in the trial.
TRIALAMT: Payment amount during the trial period. For example, zero.
You must set parameter $fields['INITAMT'] = $10; and other parameters for recurring payment to $100 for month:
$fields['INITAMT'] = 10;$fields['L_PAYMENTREQUEST_0_AMT0'] = 100;$fields['AMT'] = 100;
In this case you will charge 10$ immediately and after that each month will charge $100 for recurring payment.
Here one simple (PHP) example how to set a transaction with several products (also recurring payment):
// Parameters for SetExpressCheckout, which will be sent to PayPal
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Product description';
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] .
' $'.$product->price.'/month';
$padata['L_PAYMENTREQUEST_0_DESC0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] .
' $'.$product->price.'/month';$padata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$padata['PAYMENTREQUEST_0_DESC'] = $product->name;
$padata['RETURNURL'] = 'http://site_url/paypal/returnurl';
$padata['CANCELURL'] = 'http://site_url/paypal/cancelurl';
$padata['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD';
$padata['PAYMENTREQUEST_0_PAYMENTACTION'] = 'SALE';
$padata['PAYMENTREQUEST_0_ITEMAMT'] = $product->price;$padata['PAYMENTREQUEST_0_AMT'] = $product->price;$padata['L_BILLINGTYPE0'] = 'RecurringPayments';$padata['L_PAYMENTREQUEST_0_NAME0'] = $product->name;$padata['L_PAYMENTREQUEST_0_NUMBER0'] = '322';$padata['L_PAYMENTREQUEST_0_QTY0'] = '1';$padata['L_PAYMENTREQUEST_0_AMT0'] = $product->price;
$padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name';$hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price;
$paypal_data = http_build_query($padata);
$httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $paypal_data);
//Respond according to message we receive from Paypal
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){
//Redirect user to PayPal store with Token received.
$paypalurl ='https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';
header('Location: '.$paypalurl);
}else{
echo 'Error : '.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'';
}
Script after get token on returnurl:
$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Recurring Description';$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$pr->price.'/month';$hosteddata['L_PAYMENTREQUEST_0_NAME0'] = $pr->name;$hosteddata['PROFILEREFERENCE'] = $GetExpressCheckoutDetails['L_PAYMENTREQUEST_0_NUMBER0'];$hosteddata['PROFILESTARTDATE'] = date('Y-m-d') . 'T' . date('H:i:s').'Z';$hosteddata['SUBSCRIBERNAME'] = $GetExpressCheckoutDetails['FIRSTNAME'] . ' ' . $GetExpressCheckoutDetails['LASTNAME'];$hosteddata['TOKEN'] = urlencode($_POST['token']);$hosteddata['DESC'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'];$hosteddata['AMT'] = $pr->price;$hosteddata['BILLINGPERIOD'] = 'Month';$hosteddata['BILLINGFREQUENCY'] = '1';$hosteddata['TOTALBILLINGCYCLES'] = '12';$hosteddata['REGULARTOTALBILLINGCYCLES'] = '1';$hosteddata['VERSION'] = '74.0';$hosteddata['MAXFAILEDPAYMENTS'] = '1';$hosteddata['L_PAYMENTREQUEST_0_QTY0'] = '1';$hosteddata['L_BILLINGTYPE0'] = 'RecurringPayments';$hosteddata['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Digital';$hosteddata['L_PAYMENTREQUEST_0_AMT0'] = $pr->price;$hosteddata['INITAMT'] = $pr->price;$hosteddata['L_PAYMENTREQUEST_0_NUMBER0'] = $pr->id;$hosteddata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name';
$hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price;
$paypal_data = http_build_query($hosteddata);
$hosted_saas_response = $this->PPHttpPost('CreateRecurringPaymentsProfile', $paypal_data);
I used a separate method to post parameters to paypal
private function PPHttpPost( $methodName_, $nvpStr_ ) {
$api_username = 'yourpaypal#email.com';
$api_password = 'QWEQWEWQEQWEQEQWE';$api_signature = 'WQEQWEQWEQWEWQEQWEQWEQWEQWEQWE.cT';$api_endpoint = "https://api-3t.paypal.com/nvp";$version = '124.0';
$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $api_endpoint);curl_setopt($ch, CURLOPT_VERBOSE, 1);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$api_password&USER=$api_username&SIGNATURE=$api_signature&$nvpStr_";
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);$httpResponse = curl_exec($ch);if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');}// Extract the response details.$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();foreach ($httpResponseAr as $i => $value) { $tmpAr = explode("=", $value); if(sizeof($tmpAr) > 1) { $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1]; }}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) { exit("Invalid HTTP Response for POST request($nvpreq) to $api_endpoint.");
}
return $httpParsedResponseAr;
}
so I've been trying to set up Paypal IPN, and been trying tonnes of different solutions to get my IPN to validate. For some reason, it works fine when I'm using Sanbox paypal, but as soon as I try to use the live version, nothing happens. No error logs, no IPN logs, nothing. I'm just lost.
I was wondering if any new eyes would spot the problem. Here's my paypal.php class:
<?php
session_start();
$base = "/var/www/html/";
include("db.php");
require_once('paypal.class.php'); // include the class file
$p = new paypal_class; // initiate an instance of the class
//$p->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; // testing paypal url
$p->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; // paypal url
// setup a variable for this script (ie: 'http://www.micahcarrick.com/paypal.php')
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
// if there is not action variable, set the default action of 'process'
if (empty($_GET['action'])) $_GET['action'] = 'process';
if (empty($_GET['amm'])) $_GET['amm'] = '1';
$EMAIL = 'emailaddresshere';
switch ($_GET['action']) {
case 'process': // Process and order...
if (empty($_GET['prod'])){
header("Location: confirm-product.php"); //Was donate.php (but no file for that, so might be confirm-product)
exit;
}
if (empty($_GET['username'])){
if($_GET['action'] = 'process'){
header("Location: confirm-product.php"); // was donate.php as well
exit;
}
}
//if(!isset($_SESSION["username"])) {
// header("Location: login.php");
// exit;
//}
//include("include.php");
//die("donation is temporarily disabled!");
// There should be no output at this point. To process the POST data,
// the submit_paypal_post() function will output all the HTML tags which
// contains a FORM which is submited instantaneously using the BODY onload
// attribute. In other words, don't echo or printf anything when you're
// going to be calling the submit_paypal_post() function.
// This is where you would have your form validation and all that jazz.
// You would take your POST vars and load them into the class like below,
// only using the POST values instead of constant string expressions.
// For example, after ensureing all the POST variables from your custom
// order form are valid, you might have:
//
// $p->add_field('first_name', $_POST['first_name']);
// $p->add_field('last_name', $_POST['last_name']);
$price = '10.00';
if($_GET['prod'] == 1)
$price = '10.00';
if($_GET['prod'] == 2)
$price = '45.00';
if($_GET['prod'] == 3)
$price = '80.00';
if($_GET['prod'] == 4)
$price = '300.00';
if($_GET['prod'] == 5) //remove/change prod 5 after testing
$price = '0.01';
$name = '1K Donator Points';
if ($_GET['prod'] == 1)
$name = '1K Donator Points';
if ($_GET['prod'] == 2)
$name = '5K Donator Points';
if ($_GET['prod'] == 3)
$name = '10K Donator Points';
if ($_GET['prod'] == 4)
$name = '50K Donator Points';
if ($_GET['prod'] == 5)
$name = 'Testing Payment';
$p->add_field('custom', $_GET['username']);
$p->add_field('business', $EMAIL);
$p->add_field('return', $this_script.'?action=success');
$p->add_field('cancel_return', $this_script.'?action=cancel');
$p->add_field('notify_url', $this_script.'?action=ipn');
$p->add_field('item_name', ''.$name);
$p->add_field('item_number', $_GET['prod']);
$p->add_field('currency_code', 'USD');
$p->add_field('amount', $price);
//$p->add_field('quantity', $_GET['amm']);
$p->add_field('lc', 'GB');
$p->submit_paypal_post(); // submit the fields to paypal
// $p->dump_fields(); // for debugging, output a table of all the fields
break;
case 'success': // Order was successful...
// This is where you would probably want to thank the user for their order
// or what have you. The order information at this point is in POST
// variables. However, you don't want to "process" the order until you
// get validation from the IPN. That's where you would have the code to
// email an admin, update the database with payment status, activate a
// membership, etc.
//include("include.php");
echo "<h2>Donation Successful</h2><p>Your payment has been completed.</p>";
// You could also simply re-direct them to another page, or your own
// order status page which presents the user with the status of their
// order based on a database (which can be modified with the IPN code
// below).
break;
case 'cancel': // Order was canceled...
// The order was canceled before being completed.
//include("include.php");
echo "<h2>Payment Cancelled</h2><p>Your payment was cancelled.</p>";
break;
case 'ipn': // Paypal is calling page for IPN validation...
// It's important to remember that paypal calling this script. There
// is no output here. This is where you validate the IPN data and if it's
// valid, update your database to signify that the user has payed. If
// you try and use an echo or printf function here it's not going to do you
// a bit of good. This is on the "backend". That is why, by default, the
// class logs all IPN data to a text file.
if ($p->validate_ipn()) {
error_log("Made it to validating IPN", 3, "myerrors.log");
// Payment has been recieved and IPN is verified. This is where you
// update your database to activate or process the order, or setup
// the database with the user's order details, email an administrator,
// etc. You can access a slew of information via the ipn_data() array.
// Check the paypal documentation for specifics on what information
// is available in the IPN POST variables. Basically, all the POST vars
// which paypal sends, which we send back for validation, are now stored
// in the ipn_data() array.
if($p->ipn_data["payment_status"] != "Completed") die();
error_log("Payment Status = Completed, if this message shows - ", 3, "myerrors.log");
if($p->ipn_data["mc_gross"] > 0 && strcmp ($p->ipn_data["business"],$EMAIL) == 0) {
error_log("Blah blah blah 33", 3, "myerrors.log");
$user = $p->ipn_data["custom"];
$date = $p->ipn_data["payment_date"];
$prodid = $p->ipn_data["item_number"];
$amount = $p->ipn_data["mc_gross"];
$amountTickets = 1;
$user = str_replace("-", "_", $user);
$user = str_replace(" ", "_", $user);
$user = mysqli_real_escape_string($mysqli, $user);
$prodid = mysqli_real_escape_string($mysqli, $prodid);
$amount = mysqli_real_escape_string($mysqli, $amount);
$mysqli = new mysqli("host", "name", "pass", "db");
if ($mysqli->connect_error) {
// error_log("Connection Failed to Database", 3, "myerrors.log");
}
$query = "INSERT INTO donation (username, time, productid, price, tickets) VALUES ('".$user."', '".$date."', '".$prodid."', '".$amount."', '".$amountTickets."');";
$mysqli->query($query);
//
error_log("Passed through MySql Table insertion lines.", 3, "myerrors.log");
}
error_log(" - Finished validating IPN process.", 3, "myerrors.log");
}
break;
}
?>
And here's my paypal.class.php class
<?php
/*******************************************************************************
* PHP Paypal IPN Integration Class
*******************************************************************************
* Author: Micah Carrick
* Email: email#micahcarrick.com
* Website: http://www.micahcarrick.com
*
* File: paypal.class.php
* Version: 1.3.0
* Copyright: (c) 2005 - Micah Carrick
* You are free to use, distribute, and modify this software
* under the terms of the GNU General Public License. See the
* included license.txt file.
*
*******************************************************************************
*/
class paypal_class {
var $last_error; // holds the last error encountered
var $ipn_log; // bool: log IPN results to text file?
var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN
var $fields = array(); // array holds the fields to submit to paypal
public $timeout = 30;
private $post_data = array();
private $post_uri = '';
private $response_status = '';
private $response = '';
const PAYPAL_HOST = 'www.paypal.com';
function paypal_class() {
// initialization constructor. Called when class is created.
$this->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; //real one
// $this->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; //testing one
$this->last_error = '';
$this->ipn_log_file = '.ipn_results.log';
$this->ipn_log = true;
$this->ipn_response = '';
// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
$this->add_field('rm','2'); // Return method = POST
$this->add_field('cmd','_xclick');
}
public function getPostUri() {
return $this->post_uri;
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function submit_paypal_post() {
// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the
// BODY element's onLoad attribute. We do this so that you can validate
// any POST vars from you custom form before submitting to paypal. So
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.
// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.
echo "<html>\n";
echo "<head><title>Processing Payment...</title></head>\n";
echo "<body onLoad=\"document.forms['paypal_form'].submit();\">\n";
echo "<center><h2>Please wait, your order is being processed and you";
echo " will be redirected to the paypal website.</h2></center>\n";
echo "<form method=\"post\" name=\"paypal_form\" ";
echo "action=\"".$this->paypal_url."\">\n";
foreach ($this->fields as $name => $value) {
echo "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n";
}
echo "<center><br/><br/>If you are not automatically redirected to ";
echo "paypal within 5 seconds...<br/><br/>\n";
echo "<input type=\"submit\" value=\"Click Here\"></center>\n";
echo "</form>\n";
echo "</body></html>\n";
}
function validate_ipn() {
// parse the paypal URL
// $url_parsed=parse_url($this->paypal_url);
error_log(" - Parsed URL.", 3, "myerrors.log"); //remove after
// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = ''; //old
// $post_string="cmd=_notify-validate"; //new
foreach ($_POST as $field=>$value) {
$this->ipn_data["$field"] = $value;
$post_string .= $field.'='.urlencode(stripslashes($value)).'&'; //old
// $post_string .= '&' . $field.'='.urlencode(stripslashes($value)); //new
}
$post_string.="cmd=_notify-validate"; // append ipn command
error_log(" - Into ValidatingIPN, Line 187.", 3, "myerrors.log"); //remove after
// open the connection to paypal
// $fp = fsockopen($url_parsed['host'], 443, $errnum, $errstr, 30); //old real one
// $fp = fsockopen('ssl://www.paypal.com', 443, $errnum, $errstr, 30); //try this
// $fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30); //try this
// $fp = fsockopen('https://www.paypal.com', 443, $errnum, $errstr, 30);
// $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); //testing one
/* if ($url_parsed['scheme'] == 'https') {
$url_parsed['port'] = 443;
$ssl = 'ssl://';
} else {
$url_parsed['port'] = 80;
$ssl = '';
}
$fp = fsockopen($ssl.$url_parsed['host'], $url_parsed['port'], $errnum, $errstr, 30); */
//Real One v2
$uri = 'ssl://www.paypal.com';
$port = '443';
$this->post_uri = $uri.'/cgi-bin/webscr';
$fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
if(!$fp) {
throw new Exception("fsockopen error: [$errno] $errstr");
}
// Post the data back to paypal
// fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n"); //old
/* fputs($fp, "POST /cgi-bin/webscr HTTP/1.1\r\n");
fputs($fp, "Host: www.sandbox.paypal.com\r\n"); //sandbox - www.sandbox.paypal.com
fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-Length: ".strlen($post_string)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n"); */
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.paypal.com\r\n"; //real - www.paypal.com
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: ".strlen($post_string)."\r\n";
$header .= "Connection: Close\r\n\r\n";
fputs($fp, $header.$post_string."\r\n\r\n");
error_log(" - Connected to paypal connection. Posted Data to paypal.", 3, "myerrors.log"); //remove after
// loop through the response from the server and append to variable
while(!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024); //old
}
fclose($fp); // close connection
// if (eregi("VERIFIED",$this->ipn_response)) { //old
if (preg_match("VERIFIED", $this->ipn_response)) { //new ~VERIFIED~i for sandbox
// Valid IPN transaction.
error_log(" - Valid IPN Transaction.", 3, "myerrors.log"); //remove after
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
error_log(" - IPN Validation Failed", 3, "myerrors.log"); //remove after
$this->log_ipn_results(true); //Default: false
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log) return; // is logging turned off?
// Timestamp
$text = '['.date('m/d/Y g:i A').'] - ';
// Success or failure being logged?
if ($success) $text .= "SUCCESS!\n";
else $text .= 'FAIL: '.$this->last_error."\n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key=>$value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
// Write to log
$fp=fopen($this->ipn_log_file,'a');
fwrite($fp, $text . "\n\n");
fclose($fp); // close file
}
function dump_fields() {
// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.
echo "<h3>paypal_class->dump_fields() Output:</h3>";
echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
<tr>
<td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
<td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>
</tr>";
ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "<tr><td>$key</td><td>".urldecode($value)." </td></tr>";
}
echo "</table><br>";
}
}
I am using CodeIgniter for an iPhone app I have. The app allows for users to share images to specific individuals. It works great great, but it seems that after a certain amount of pictures to sent to an individual, posts fail to upload. I was wondering if there is something within CodeIgniter that is causing this issue and how to fix it.
here is part of our config file:
$config['proxy_ips'] = '';
$config['upload_group_path'] = "./upload/group";
$config['upload_user_path'] = "./upload/users";
$config['upload_photo_path'] = "./upload/photo";
$config['upload_video_path'] = "./upload/video";
$config['upload_weblink_path'] = "./upload/weblink";
$config['upload_drawing_path'] = "./upload/drawing";
$config['upload_text_path'] = "./upload/text";
$config['upload_movietype'] = 'mp4|flv|3gp|wmv';
$config['upload_moviesize'] = 100 * 1024; // 100M
$config['upload_alltype'] = '*';
$config['upload_allsize'] = 100 * 1024; // 100M
$config['upload_imgtype'] = 'gif|jpg|png|bmp|jpeg|jpe';
$config['upload_imgsize'] = 5 * 1024; // 5M
$config['upload_thumb_mw'] = '80';
$config['upload_thumb_mh'] = '60';
$config['upload_kmltype'] = 'kml';
$config['upload_kmlsize'] = 10 * 1024; // 10M
$config['main_category'] = array(
'user' => 'Users',
'photo' => 'Photos',
);
$config['difficulty'] = array(
'Easy' => 'Easy',
'Moderate' => 'Moderate',
'Difficult' => 'Difficult',
);
$config['max_count_per_page'] = 5;
$config['thumb_name'] = "_thumb";
$config['photo_name'] = "_photo";
And part of our api file (that draws the error 'fail to upload' in xcode's output):
$tbl_name = "posts";
$new_idx = $this->api_m->get_next_insert_idx($tbl_name);
if (isset($_FILES['datafile']) && $_FILES['datafile']['name'] != '') {
$conf = array();
$conf['upload_path'] = $this->api_m->get_upload_path($postType, $ownerID."_".$format);
$conf['allowed_types'] = $this->config->item('upload_alltype');
$conf['max_size'] = $this->config->item('upload_allsize');
$conf['overwrite'] = FALSE;
$conf['remove_spaces'] = TRUE;
if (!file_exists($conf['upload_path'])) {
mkdir($conf['upload_path']);
}
$this->upload->initialize($conf);
if ($this->upload->do_upload('datafile')) {
$fileinfo = $this->upload->data();
if ($fileinfo['file_size'] > 0) {
$postURL = base_url().substr($conf['upload_path'], 2)."/".$fileinfo['file_name'];
if ($postType == "video") {
$referenceData = base_url().substr($conf['upload_path'], 2)."/".$fileinfo['file_name'];
if (isset($_FILES['thumbfile']) && $_FILES['thumbfile']['name'] != '') {
$conf = array();
$conf['upload_path'] = $this->api_m->get_upload_path($postType, $ownerID."_".$format);
$conf['allowed_types'] = $this->config->item('upload_alltype');
$conf['max_size'] = $this->config->item('upload_allsize');
$conf['overwrite'] = FALSE;
$conf['remove_spaces'] = TRUE;
if (!file_exists($conf['upload_path'])) {
mkdir($conf['upload_path']);
}
$this->upload->initialize($conf);
if ($this->upload->do_upload('thumbfile')) {
$fileinfo = $this->upload->data();
$baseName = $this->api_m->_img_resize($postType, $fileinfo, $fileinfo['raw_name'], $new_idx);
$postURL = base_url().substr($conf['upload_path'], 2)."/".$baseName;
$baseName = $this->api_m->_img_thumb($postType, $fileinfo, $fileinfo['raw_name'], $new_idx);
$thumbURL = base_url().substr($conf['upload_path'], 2)."/".$baseName;
}
}
} else {
$baseName = $this->api_m->_img_thumb($postType, $fileinfo, $fileinfo['raw_name'], $new_idx);
$thumbURL = base_url().substr($conf['upload_path'], 2)."/".$baseName;
}
$uploadMsg = "success";
}
} else {
$uploadMsg = "fail to upload";
}
} else {
$uploadMsg = "select the post data";
}
There is no limit in Codeigniter for how many files you can upload, however are you uploading more than one file at a time so that you might reach the limit for how big files you may upload? Either in CI config or the server config.
EDIT!
Try using $this->upload->display_errors() to see what's is going wrong according to CI. My guess now is that the filename allready exists, but I'm curios to see what you get.
2nd EDIT!
In your configuration or before you load your upload class you can set the setting: max_filename_increment. When overwrite is set to FALSE, use this to set the maximum filename increment for CodeIgniter to append to the filename.
$conf['max_filename_increment'] = // What ever number you think is reasonable
Fix this and you should be good to go again :)
3rd EDIT!
I'm sorry that setting isn't available yet. So either you have to add your own upload class in your applications folder there are guides for how to add custom libraries to codeigniter else you will have to edit the Upload class in system. Note that it is not recommended to update anything in the system folder since it would be overwritten if you would update you version of CI later.
But I will of course let you know how to edit the class if you want to;
In the folder libraries in CI system you find the file Upload.php. In the latest version you find the function set_filename() on row 390. Scroll down to row 406 and you should see
for ($i = 1; $i < 100; $i++)
This is the loop that takes too few turns for your file names to be incremented. exchange 100 to a new number and try again.
for ($i = 1; $i < 1000; $i++)
That will loop ten times more than before, but I guess the limit is there for performance so check your response times before and after editing this and when uploading 3-500 files with the same name?
Regards