You've got a few bugs in your regexps. Load up this checker on your site if you want to play with these.
The pattern ^((products/|product/|)PN[0-9-]+)/
does not match "URL/products/PN123" or "URL/product/PN123" or "URL/PN123" and return the PN123 because of the embedded match string and the trailing slash. You can hide the product(s)/ and make the trailing / optional as below.
I don't like using the ! prefix in rule patterns, especially when using a grouped parts. Too easy to shoot yourself in the foot. I prefer a cond followed by a null rule or a negative lookahead.
- Fall-though match rules can trigger the postfix bug so again I avoid them. The engine loops retrying .htaccess files (because they are evaluated in a "Per Directory context")
until no match so I find it just a LOT safer to always use the [L] flag
- Again because of this looping you need to assure that your rules will terminate and its better to do this in a simple transparent manner. In this case you don't seem to want to
rewrite URIs which map to real files so why not hoist the
-f
test to the top and all other rules can then assume that this condition is true.
- The two search rule mean that the cat=acc123 parameter is used if the request is for /acc123/ etc and search= otherwise. Is this what you want?
- You need to include the QSA flag unless you want to ignore any existing parameters.
- The environment variable USCOR (I stick to uppercase) becomes REDIRECT_USCOR on the next pass so this is what you test for. I assume that a rule follows this last cond
Putting these all together gets:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# The rewrite engine loops in a Per Dir context. We don't remap real files so:
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Open the product details page with the Product Number with PN prefix
RewriteRule ^(?:products?)?(PN\d+)/?$ product.php?pno=$1 [L,NC,QSA]
# Open the product search page for a particular category
RewriteRule ^((?:bat|ref|acc)[A-Za-z0-9-]+)/?$ search.php?cat=$1 [L,NC,QSA]
#open the product search page for a particular category
RewriteRule ^([A-Za-z0-9-_.,]+)/?$ search.php?search=$1 [L,NC,QSA]
RewriteRule \.(?!(php|html)$) - [S=4,NC]
RewriteRule ^(.*?)_(.*?)_(.*?)_(.*?)_(.*)$ $1-$2-$3-$4-$5 [E=USCOR:Yes, L]
RewriteRule ^(.*?)_(.*?)_(.*?)_(.*)$ $1-$2-$3-$4 [E=USCOR:Yes, L]
RewriteRule ^(.*?)_(.*?)_(.*)$ $1-$2-$3 [E=USCOR:Yes, L]
RewriteRule ^(.*?)_(.*)$ $1-$2 [E=USCOR:Yes, L]
I am not sure what you want to do with %{ENV:REDIRECT_USCOR} now without the additional rules and logic, though it will be available to the script as $_SERVER["REDIRECT_USCOR']
.