.htaccess Redirects do not work

Hi



Hoping I’ve missed something obvious, but can’t to pinpoint it.



Our old cart used categories/product URL’s like this, both of which returned the same content without the 404 issues I’m having with CS-Cart:



domain.com/categories/Root-Category/Sub-Category

OR

domain.com/categories/root-category/sub-category

and

domain.com/products/Product-Name.html

OR

domain.com/categories/product-name.html



These both directed to one valid category/product page, regardless of the capitalisation (uppercase) character of each word.



Unfortunately in the old cart, the URL was generated automatically from the product name, so a product with a symbol character in the URL, would produce an ugly URL, such as a product called ‘Category - Name’ would produce:```php


http://www.domain.com/category/Category-%252d-Name/

CS-Cart strips these symbols out, therefore the product URL has become:<br />
```php
http://www.domain.com/categories/category-name/
```<br />
<br />
So, I have set 301 redirects up in .htaccess like so for the new category URL's:<br />
```php
<br />
redirect 301 /categories/Category-Name/ http://www.domain.com/category-name/
```<br />
<br />
This, for some bizarre reason, redirects to:<br />
```php
http://www.domain.com/Category-Name/?sef_rewrite=1
```<br />
Which produces a 404 error, but, why does it change to Uppercase and why is '?sef_rewrite=1' in there?<br />
<br />
In CS-Cart, pages only seem to be served with some dodgy hack shown below, so in this CS-Cart, to 'resolve' this, category and product URL's only seem to be served with some dodgy hack shown below.<br />
<br />
In index.php:<br />
```php
$url = $_SERVER['REQUEST_URI'];<br />
$pattern = '/([A-Z]+)/';<br />
<br />
if(preg_match($pattern, $url)) {<br />
    $new_url = strtolower($url);<br />
<br />
    Header( 'HTTP/1.1 301 Moved Permanently' );<br />
    Header( 'Location: ' . $new_url );<br />
    exit;<br />
}
```<br />
<br />
This forces Uppercase to Lowercase in the URL and therefore redirects the customer to the appropriate page. However, the code above seems a dirty way of doing it and I can't for the life of me figure out why the .htaccess isn't working properly.<br />
<br />
If I use a RewriteMatch function for redirecting /Categories/Category-Name/ by stripping 'Categories/', the page returns http://www.domain.com/?sef_rewrite=1<br />
<br />
Therefore the dirt index.php hack above seems to be the only solution, which appears to break other functions anyway.<br />
<br />
Here's the .htaccess, any clues? I know this is a looooong post, so if you've read it all, thanks for sticking with me!<br />
```php
<br />
DirectoryIndex index.html index.php<br />
<br />
<IfModule mod_rewrite.c><br />
<br />
RewriteEngine on<br />
<br />
# Some hostings require RewriteBase to be uncommented<br />
<br />
# Example:<br />
<br />
# Your store url is http://www.yourcompany.com/store/cscart<br />
<br />
# So "RewriteBase" should be:<br />
<br />
# RewriteBase /store/cscart <br />
<br />
# RewriteBase /<br />
<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
<br />
RewriteRule . index.php?sef_rewrite=1 [L,QSA]<br />
<br />
RewriteRule ^(.*\.(js|css))$ smartoptimizer/?$1<br />
<br />
</IfModule>     <br />
<br />
        <IfModule !mod_expires.c><br />
<br />
                RewriteCond %{REQUEST_FILENAME} -f<br />
<br />
                RewriteRule ^(.*\.(ico|gif|jpg|jpeg|png|swf|css|js|html?|xml|txt))$ smartoptimizer/?$1<br />
<br />
        </IfModule><br />
<br />
<IfModule mod_expires.c><br />
<br />
        <FilesMatch "\.(ico|gif|jpg|jpeg|png|swf|css|js|html?|xml|txt)$"><br />
<br />
                ExpiresActive On<br />
<br />
                ExpiresDefault "access plus 10 years"<br />
<br />
        </FilesMatch><br />
<br />
</IfModule><br />
<br />
<IfModule mod_headers.c><br />
<br />
 <FilesMatch \.(css|js)$><br />
<br />
 Header append Vary User-Agent<br />
<br />
 Header append Vary Accept-Encoding<br />
<br />
 Header append Cache-Control private<br />
<br />
 </FilesMatch><br />
<br />
 <FilesMatch \.(bmp|png|gif|jpe?g|ico|flv|wmv|asf|asx|wma|wax|wmx|wm|swf|pdf|doc|rtf|xls|ppt|eot|ttf|otf|svg)$><br />
<br />
 Header append Cache-Control public<br />
<br />
 </FilesMatch><br />
<br />
 <FilesMatch \.(js|css|bmp|png|gif|jpe?g|ico|flv|wmv|asf|asx|wma|wax|wmx|wm|swf|pdf|doc|rtf|xls|ppt)$><br />
<br />
Header unset ETag<br />
<br />
FileETag None<br />
<br />
 </FilesMatch><br />
<br />
</IfModule><br />
<br />
<br />
# Turn on Expires and set default to 0<br />
<br />
<IfModule mod_expires.c><br />
<br />
 ExpiresActive On<br />
<br />
 <FilesMatch \.css$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType text/css A315360000<br />
<br />
 <FilesMatch \.js$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType text/javascript A315360000<br />
<br />
 ExpiresByType application/javascript A315360000<br />
<br />
 ExpiresByType application/x-javascript A315360000<br />
<br />
 ExpiresByType text/x-js A315360000<br />
<br />
 ExpiresByType text/ecmascript A315360000<br />
<br />
 ExpiresByType application/ecmascript A315360000<br />
<br />
 ExpiresByType text/vbscript A315360000<br />
<br />
 ExpiresByType text/fluffscript A315360000<br />
<br />
 <FilesMatch \.(bmp|png|gif|jpe?g|ico)$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType image/gif A315360000<br />
<br />
 ExpiresByType image/png A315360000<br />
<br />
 ExpiresByType image/jpeg A315360000<br />
<br />
 ExpiresByType image/x-icon A315360000<br />
<br />
 ExpiresByType image/bmp A315360000<br />
<br />
 <FilesMatch \.(eot|ttf|otf|svg)$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType application/x-font-opentype A315360000<br />
<br />
 ExpiresByType application/x-font-truetype A315360000<br />
<br />
 ExpiresByType application/x-font-ttf A315360000<br />
<br />
 ExpiresByType application/x-font A315360000<br />
<br />
 ExpiresByType font/opentype A315360000<br />
<br />
 ExpiresByType font/otf A315360000<br />
<br />
 ExpiresByType application/vnd.oasis.opendocument.formula-template A315360000<br />
<br />
 ExpiresByType image/svg+xml A315360000<br />
<br />
 ExpiresByType application/vnd.ms-fontobject A315360000<br />
<br />
 ExpiresByType font/woff A315360000<br />
<br />
 <FilesMatch \.(flv|wmv|asf|asx|wma|wax|wmx|wm)$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType video/x-flv A315360000<br />
<br />
 ExpiresByType video/x-ms-wmv A315360000<br />
<br />
 ExpiresByType video/x-ms-asf A315360000<br />
<br />
 ExpiresByType video/x-ms-asx A315360000<br />
<br />
 ExpiresByType video/x-ms-wma A315360000<br />
<br />
 ExpiresByType video/x-ms-wax A315360000<br />
<br />
 ExpiresByType video/x-ms-wmx A315360000<br />
<br />
 ExpiresByType video/x-ms-wm A315360000<br />
<br />
 <FilesMatch \.(swf|pdf|doc|rtf|xls|ppt)$><br />
<br />
 ExpiresDefault "access plus 10 years"<br />
<br />
 </FilesMatch><br />
<br />
 ExpiresByType application/x-shockwave-flash A315360000<br />
<br />
 ExpiresByType application/pdf A315360000<br />
<br />
 ExpiresByType application/msword A315360000<br />
<br />
 ExpiresByType application/rtf A315360000<br />
<br />
 ExpiresByType application/vnd.ms-excel A315360000<br />
<br />
 ExpiresByType application/vnd.ms-powerpoint A315360000<br />
<br />
</IfModule><br />
<br />
FileETag none<br />
<br />
<IfModule mod_deflate.c><br />
<br />
<FilesMatch "\.(php|html)$"><br />
<br />
SetOutputFilter DEFLATE<br />
<br />
</FilesMatch><br />
<br />
</IfModule><br />
<br />
#Strip categories/ from the URL thus .com/category-name/<br />
<br />
RedirectMatch 301 ^/categories/(.*)$ http://www.domain.com/$1<br />
<br />
redirect 301 /categories/Category-Name/ http://www.domain.co.uk/category-name
``` <br />
<br />
Even if I change this:```php
RedirectMatch 301 ^/categories/(.*)$ http://www.domain.com/$1
```<br />
To redirect .com/products/Product-Name.html to .com/product-name.html, this whole setup still doesn't work.<br />
<br />
<br />
Sorry for the long rambling (incoherent) post, it's late  <img src="upload://2gefrk5yIQmBF7b3nb7uvIojpeG.gif" class="bbc_emoticon" alt=":("> <br />
<br />
I would appreciate your thoughts if you could spare a moment to think this one through! Thanks

Please contact me if you can provide a suitable solution, we need this resolved ASAP and therefore are looking to pay someone for their assistance.



Thanks

Hi,



You could try the redirect as the first rewrite rule before any other rules are executed eg just after # RewriteBase /



:unsure:

Yep try putting your redirect before:


Some hostings require RewriteBase to be uncommented

Thanks guys, I’ve moved the appropriate htaccess rules to where you suggest and now this HALF works, very strange indeed…



Old Product URL, note all Old URL’s capitalised the first letter of every word in the category/product name when generating the URL):

http://www.domain.com/products/Product-Name.html
```<br />
This now strips /products, therefore creates:<br />
```php
http://www.domain.com/Product-Name.html?sef_rewrite=1
```<br />
This page actually now works, served regardless if the URL is in Uppercase or Lowercase. I'd rather not have "?sef_rewrite=1" - but at least the customers are now getting to the product pages ok.<br />
<br />
However, URL's ONLY work in lowercase for categories. Why?  <img src="upload://fySPYAyUqExEaFrjtsIiAE6aRPv.gif" class="bbc_emoticon" alt=":blink:"><br />
<br />
I have now removed the dirty hack to index.php to redirect Uppercase to Lowercase in URL's, as this was causing some other issues with the cart, but why, oh why, do Product URL's work in Uppercase but Category URL's do not?!<br />
<br />
Thanks for your suggestions!

OK…

http://www.domain.com/categories/Category-Name/Subcategory-Name/

Redirects to:

http://www.domain.com/categories/category-name/Subcategory-Name/



NOTE: the first category is in lowercase, but the remainder is not, therefore still produces a 404 error.



So now all my root categories redirect, but anything below root categories, does not. Not good at all for a site with this many categories.

Hi,



If you have access to apache httpd.conf you could try adding this (note this will only work in .conf file or check with hosting provider)




RewriteEngine on
RewriteMap lc int:tolower





then add this code to your rewrite rules in .htaccess file


RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule (.*) ${lc:http://www.yourdomain.com/$1} [R=301,L]




This will check for uppercase letter within url and redirect to lowercase url

Thanks - that does exactly what is required for the URL’s, now all old URL’s (categories and products) redirect to the new CS-Cart equivalent, via 301 permanent redirect, so it’s only a matter of time before Google reindex the new URL’s.



The major issue with this is with image paths, because it also appears to change the file path URL’s, therefore Image-Name.jpg is now looking for image-name.jpg, despite the file actually being ‘Image-Name.jpg’ on the server, thus, the image does not show.



Any ideas how I can restrict this functionality to the site URL and ignore file path URL’s? Sounds like a super long shot, but then thought…impossible is nothing :lol:

Hi,



The second line is another rewrite condition, if file is an image, css, or js (you may wish to add php to this list) then no redirect. This should restrict redirect to only categories and products.


<br />
RewriteCond %{REQUEST_URI} [A-Z]<br />
RewriteCond %{REQUEST_FILENAME} !\.(?:png|gif|ico|swf|jpe?g|js|css)$<br />
RewriteRule (.*) ${lc:http://www.yourdomain.com/$1} [R=301,L]<br />

```<br />
<br />
Hope this does the trick  <img src="upload://fySPYAyUqExEaFrjtsIiAE6aRPv.gif" class="bbc_emoticon" alt=":blink:">

[quote name=‘Adrian8’ timestamp=‘1322309650’ post=‘126765’]

Hi,



The second line is another rewrite condition, if file is an image, css, or js (you may wish to add php to this list) then no redirect. This should restrict redirect to only categories and products.


<br />
RewriteCond %{REQUEST_URI} [A-Z]<br />
RewriteCond %{REQUEST_FILENAME} !\.(?:png|gif|ico|swf|jpe?g|js|css)$<br />
RewriteRule (.*) ${lc:http://www.yourdomain.com/$1} [R=301,L]<br />

```<br />
<br />
Hope this does the trick  <img src="upload://fySPYAyUqExEaFrjtsIiAE6aRPv.gif" class="bbc_emoticon" alt=":blink:"><br />
[/quote]<br />
<br />
Thanks! That solved the majority of issues, only problem I've got now is with jpg and jpeg images, I assume "|jpe?g|" is making use of a wildcard character - ? - but it doesn't work, jpg and jpeg's with Uppercase letters in their filename do not load, however, I have resolved it - perhaps not the best method, but still functional - by changing it to:<br />
```php
<br />
RewriteCond %{REQUEST_URI} [A-Z]<br />
RewriteCond %{REQUEST_FILENAME} !\.(?:png|gif|ico|swf|jpg|jpeg|js|css|php)$<br />
RewriteRule (.*) ${lc:http://www.domain.com/$1} [R=301,L]
```<br />
<br />
Now everything works - I had problems with product options giving an "Error" message when selecting options, this is now resolved - as well as checkout issues, with customers coming back from the PSP at checkout to a 'Declined' message, when in actual fact none of the payments were declined (you can imagine the problem this caused).<br />
<br />
Now all these issues are resolved, I had CS-Cart take a few days to diagnose the issue (based on product options not working and the checkout issues), they finally proposed a (custom development) fix yesterday - looks like I don't need it now!<br />
<br />
Many thanks - I owe you one (and a few more after that! <img src="upload://tagmsFLhR9Ka1Qsz9bY91MY71wJ.gif" class="bbc_emoticon" alt=";)">)