Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Cabbit

macrumors 68020
Original poster
Jan 30, 2006
2,128
1
Scotland
Hey there folks i am rather new to writing a .htaccess file and have only went as far to make it rewrite a route for my framework Cabbit.
Now it works for standard urls in my framwork such as http://mysite.com/controller/function/action however it falls on its bum when getting back the url from paypal(part of the framework is payments pro and express checkout) where the return is http://mysite.com/controller/function?token=thistokenfortheuser&PayerID=something
So i need it to come out as
http://mysite.com/controller/function/thistokenfortheuser/something

Also i am not sure if it is possible but it would be terrific for it to be possible that http://mysite.com/eshop/checkout is rewritten to https://mysite.com/eshop/checkout instead though as i said i don't know if this is possible and right now i can do it with php.

Thanks in advance for any help and suggestions.

current .htaccess
Code:
Options +FollowSymLinks
Options -Indexes
DirectoryIndex /public/index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule (.*) public/index.php?rt=$1 [L]
 
Something like this should work.

Code:
RewriteRule /controller/function?[a-z]+=([B][COLOR="Red"][a-z]+[/COLOR][/B])&[a-zA-Z]+=([B][COLOR="Red"][a-zA-Z]+[/COLOR][/B])$ /controller/function/$1/$2
 
this is the htaccess file now
HTML:
Options +FollowSymLinks
Options -Indexes
DirectoryIndex /public/index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) public/index.php?rt=$1 [L]
RewriteRule /products/returnexpress/?[a-z]+=([a-z]+)&[a-zA-Z]+=([a-zA-Z]+)$ /products/returnexpress/$1/$2

It still spits back http://dev.mysite.com/products/returnexpress/?token=EC-828925359S785910B&PayerID=VRAUNMCBL692W
Where i really want it to return
http://dev.mysite.com/products/returnexpress/EC-828925359S785910B/VRAUNMCBL692W

Perhaps i miss understood.

Just for my understanding, this is how the current rt works.
http://dev.mysite.com?rt=/products/returnexpress/?token=EC-828925359S785910B&PayerID=VRAUNMCBL692W
 
Well, the example you provided before wasn't representative of what you needed so that's why it didn't work. Things like character case, the types of letter allowed and such are very important when constructing regex. Here's an updated line that should accommodate the sample you provided.
Code:
RewriteRule /products/returnexpress/?[a-z]+=([A-Z0-9-]+)&[a-zA-Z]+=([A-Z0-9]+)$ /products/returnexpress/$1/$2
 
Maybe a dumb question, but do you need to escape the ? after the /products/returnexpress/ bit, or does Apache do some cleverness.

So:
Find:
Code:
/products/returnexpress/\?[a-z]+=([A-Z0-9-]+)&[a-zA-Z]+=([A-Z0-9]+)$
Replace:
Code:
/products/returnexpress/$1/$2

(obviously it needs to be run into one line, with a space between each of the sections above, I just split it up to save scrolling)
 
Maybe a dumb question, but do you need to escape the ? after the /products/returnexpress/ bit, or does Apache do some cleverness.

Good catch. You're right, it needs the backslash. Apache does have some option for looking at the query string alone, but isn't as helpful here.
 
Slightly related, Regexhibit is good for trying out perl like regular expressions.

Hasn't been developed in a while, but it is completely free and the source is available.

You use it like this, blue means matched, pink means captured, purple shows the replacement.
 

Attachments

  • Screen shot 2010-01-20 at 17.16.58.png
    Screen shot 2010-01-20 at 17.16.58.png
    92.1 KB · Views: 125
Well i tried this like ya guys said.

HTML:
Options +FollowSymLinks
Options -Indexes
DirectoryIndex /public/index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) public/index.php?rt=$1 [L]
RewriteRule /products/returnexpress/\?[a-z]+=([A-Z0-9-]+)&[a-zA-Z]+=([A-Z0-9]+)$ /products/returnexpress/$1/$2

But the URL being returned remains http://dev.mysite.com/products/returnexpress/?token=EC-20H486245S384273B&PayerID=VRAUNMCBL692W :(
 
I started wondering about this, but it's not completely clear when you said,
when getting back the url from paypal(part of the framework is payments pro and express checkout) where the return is http://mysite.com/controller/functio...erID=something

The rewrites we have been working on are applied when someone either types in the URL or clicks on a link for a certain URL, then it is rewritten to the new format. I don't know that this case necessarily falls under this. Can you explain more about the PayPal part? Is PayPal accessing a URL that needs to be rewritten? Does a file exists where the rewritten URL points to?
 
Ok well i send a request to paypal from my site at http://mysite.com/products/doexpress

That sends https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$Paypal->Token.'

Which spouts back to my return url

http://dev.mysite.com/products/returnexpress/?=token=bladebla&=payerid=bladebla

Now my problem with this is that i cant get php to read the bit after the ? because ? is already set at ?rt=$1 which is for all the internal framework stuff.
So i don't know how to get the values token and payerid out of the url unless i manually do it in the url bar but i could not expect a user to want to do with.
 
Can you share what you're trying to use to get the stuff after the ? that you're having issues with? It's not clear why you can't access that info. I've never messed with the PayPal checkout stuff so I'm still having trouble following the code logic you're using, but I think the Apache rewrite likely won't get you there based on what I think I understand on your situation.
 
I am gona sleep on it then post the code structure and ins and outs of what is happening.
 
Ok well i have slept on it for a couple days trying to work it out but i can't get my head round it.
In a nut shell it is a 3 step process.

This is the first script this sends out the request to paypal with the return address. The real address with htaccess off would be index.php?rt=products/returnexpress

PHP:
public function paypalexpress()
	{
		// SetExpressCheckout
		// On Success Will return a token with value like EC-7EG51014BE327234S
		// Customer should then be redirected by your server to URL like 
		// https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-7EG51014BE327234S
		// Customer will then enter payment at paypal.com and upon success customer will be sent back to the $ReturnURL
		// that you provided in the operation with the tokon and PayerID appended as parameters to the $ReturnURL
		//==========================================================================================================
		$API = $this->Cabbit->Paypal;
		
		$API_USERNAME = '*';
		
		$API_PASSWORD = '*';
		
		$API_SIGNATURE = '*';
		
		$API->prepare($API_USERNAME, $API_PASSWORD, $API_SIGNATURE);
		
		$Paypal = $API->selectOperation('SetExpressCheckout');
		
		$cart = $_SESSION['cart'];
		if ($cart) 
		{
			$items = explode(',',$cart);
			$contents = array();
			foreach ($items as $item) 
			{
				$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
			}			
			foreach ($contents as $id=>$qty) 
			{
				// Get product data from product model
				$productdata = new model_product;
				$products = $productdata->productData(); // gets the user data array
				
				// Basket
				foreach ($products as $key => $value) 
				{
					if ($key == $id)
					{
						// Update total
						$item = $value['price'] * $qty;
					}
				}
				$item_total = $item_total + $item;
			}
		}
		$productdata = new model_product;
		$shippingCost = $productdata->shippingRate();
		$shipping    = $_SESSION["ShippingRate"];
		
		$OrderTotal = $item_total + $shipping;
		
		$ReturnURL = 'http://dev.mysite.com/products/returnexpress/';
		
		$CancelURL = 'http://dev.mysite.com/';
		
		$PaymentAction = 'Sale'; // or Order
		
		$Paypal->setParams($OrderTotal, $ReturnURL, $CancelURL, $PaymentAction);
		
		$Paypal->execute();
		
		if ($Paypal->success())
		{
			$Responce->getAPIResponse();
		} 
		else 
		{
			$Responce->getAPIException();
		} 	
		header('Location: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$Responce->Token.''); // Sent user to home page
			exit();
	}

What paypal returns is http://dev.mysite.com/products/returnexpress?token=EC-7SX97880L96523901&PayerID=VRAUNMCBL692W

Which means it is http://dev.mysite.com?rt=products/returnexpress?token=EC-7SX97880L96523901&PayerID=VRAUNMCBL692W

That makes it impossible to read the contents of token.
 
I get most of that except the
Which means it is http://dev.mysite.com/?rt=products/returnexpress?token=EC-7SX97880L96523901&PayerID=VRAUNMCBL692W
From the look of the documentation it should just be that link you provided as "what paypal returns." What puts in the ?rt= part? That's what is confusing me now.

Also, I don't think it's a good idea to reuse the $Paypal variable the way you are, to capture the response. I'd recommend using a different variable, like $response.
 
The rt is the un url rewritten path to the receiving page. Paypal returns a token to the page i specify but the token it returns is ?token when my pages are all rewritten index.php?rt=class/function to /class/function to make it nice and neat.

Is there a way i could put in some conditional logic to a htaccess to rewrite index.php?token=****&payerid=****
to
index.php?rt=****/****&token=****&payerid=*****

I think that would cut out a lot of the complexity.

Paypal it self attaches the ?token to the url i give it, what would be ideal is if i could ether change the ?token or set it to return to index to php and have the url rewritten to /class/function/token/payerid/ from there rather than doing it at the /class/function/ stage.
 
Well, that's just a slight variation of what we presented before.
Code:
RewriteRule /\?token=([a-zA-Z0-9-]+)&payerid=([a-zA-Z0-9]+)$ /products/returnexpress/$1/$2/
 
^_^ thanks i'll try it.

Just to be sure
Options +FollowSymLinks
Options -Indexes
DirectoryIndex /public/index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
<-- it goes here before the normal rewrite
RewriteRule (.*) public/index.php?rt=$1 [L]
<-- or here after
 
You'll need it before as your current line will match pretty much everything and has [L] at the end so will stop processing after that for the rewrites.
 
^_^ oh thats what the L means, emm can you recommend a book i would love to know how to do this bit without needing to ask for help it seems there is more to programming than php/rails/html/css and javascript when making sites.
 
I just Google. Apache's pages tend to be overly technical, but can provide some guidance. Otherwise, I do searches like "rewriterule tutorial" or ".htaccess tips OR tutorial"
 
using

Code:
Options +FollowSymLinks
Options -Indexes
DirectoryIndex /public/index.php
RewriteEngine On
RewriteBase /
RewriteRule /\?token=([a-zA-Z0-9-]+)&payerid=([a-zA-Z0-9]+)$ /products/returnexpress/$1/$2/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) public/index.php?rt=$1 [L]

The sale is still not being redirected to the products/returnexpress/ page
http://dev.mysite.com/?token=EC-0JV78003MU996243K&PayerID=VRAUNMCBL692W

The htaccess should redirect the user to
http://dev.mysite.com/products/returnexpress/EC-0JV78003MU996243K/VRAUNMCBL692W/
 
The link has different capitalization for payerid vs PayerID. Regexes are very particular like that.
Code:
RewriteRule /\?token=([a-zA-Z0-9-]+)&PayerID=([a-zA-Z0-9]+)$ /products/returnexpress/$1/$2/
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.