Conditional .htaccess rules for same URL - .htaccess

What is the best method to combine the following two rules into one, so that users can visit domain.com/schedule and also domain.com/schedule/{day}
The rule should forward to the same controller, where I will then check the parameter
RewriteRule ^schedule/?$ index.php?_orn_shows_action=view-schedule [NC,QSA,L]
RewriteRule ^schedule/([a-zA-Z0-9-]+)/?$ index.php?_orn_shows_action=view-schedule&day=$1 [NC,QSA,L]

If you don't care whether or not you get the day parameter without a value, you can just do this:
RewriteRule ^schedule(/(([a-zA-Z0-9-]+)/?)?)?$ index.php?_orn_shows_action=view-schedule&day=$3 [NC,QSA,L]
This would capture these variations:
/schedule
/schedule/
/schedule/day
/schedule/day/
If you want to make sure not to get an empty day parameter, do this:
RewriteCond $3 ="" [OR]
RewriteCond &day=$3 ^(.*)$
RewriteRule ^schedule(/(([a-zA-Z0-9-]+)/?)?)?$ index.php?_orn_shows_action=view-schedule&day=$3 [NC,QSA,L]
Finally, if you don't expect to get a query string from the browser on these URLs, I would drop the QSA tag, since someone going to /schedule/monday?day=1 would end up setting day equal to 1, instead of to "monday". There's ways to prevent that, but if you don't need the query string, it's easier just to ignore it.

Maybe you don't have to combine it to one - try to switch their positions, second as first and first after that, so your first rule will not catch request that should be analysed by second rule.

Related

.htaccess - Heal malformed url

I need a solution. For some reason in the past seems that I generate some "bad" links for bots only.
Resume: There is a fake "page" parameter when malformed url is present. When there are 2 "page" parameters then the first one is fake, must be removed.
X is random
Remove the parameter page only when "?/?page" is detected
Good: search?pagepage=496
Bad: search?/?page=X
Good: https://example.com/search?page=496
Good: https://example.com/search?page=496&orderBy=oldest
Bad: https://example.com/search?/?page=X&page=496&orderBy=oldest
RewriteCond %{QUERY_STRING} ^(.*)&?^XXX[^&]+&?(.*)$ [NC]
RewriteRule...
Thank you guys!
UPDATE
At final, I found a solution by myself:
RewriteCond %{QUERY_STRING} ^(.*)&?^/\?page=[^&]+&?(.*)$ [NC]
RewriteRule ^/?(.*)$ /search$1?%1%2 [R=301,L]
RewriteCond %{QUERY_STRING} ^/\?page=.+&(page=.*)
RewriteRule ^(search)$ $1?%1 [R=301]
This will do the rewrite for all your URLs that have the extra page parameter you want to keep.
To make the last part optional, we would have to wrap &(page=.*) into another set of braces, and add a ? as quantifier - (&(page=.*))?.
Then the back reference would need to be changed from %1 to %2 (because we only need that inner part, we don't want the &) - but then for your URL without any real page parameter to keep, there would be no match in this place, and therefor the %2 would not be substituted with anything, but added to the URL literally.
So better to leave the above as-is, and simply add
RewriteCond %{QUERY_STRING} ^/\?page=.+
RewriteRule ^(search)$ $1 [QSD,R=301]
below those two existing lines. The pattern does not need to be any more specific (because the URLs that have a genuine page parameter at the end, have already been handled by those previous two lines.) And the QSD makes it simply drop the existing query string, so that https://example.com/search?/?page=20 results in https://example.com/search (which I assume is what you wanted here, because there is no actual page parameter to keep, correct?)

Two rules in one .htaccess file not working

Below is my code for .htaccess
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ /products/product-full-view.php?src=$1&id=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/?$ /products/product-full-view.php?src=$1&id=$2
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)$ /buy/buy-full-view.php?src=$1&id=$2
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/?$ /buy/buy-full-view.php?src=$1&id=$2
First rule is working fine but its not taking the second rule...Unable to understand what is happening here...
Original URL's are like this
www.example.com/products/product-full-view.php?src=somevalue&id=somevalue
and for second one
www.example.com/buy/buy-full-view.php?src=somevalue&id=somevalue
Please help me to run second rule also.
Thanks in advance
You're trying to match the same pattern, give or take an optional trailing slash, four times. By the time you reach the last two rules, your URL is already rewritten to something else.
You probably want something that looks more like:
RewriteEngine On
RewriteRule ^products/([0-9]+)/?$ /products/product-full-view.php?id=$1 [L]
RewriteRule ^buy/([0-9]+)/?$ /buy/buy-full-view.php?id=$1 [L]
Or:
RewriteEngine On
RewriteRule ^products/([a-zA-Z0-9_-]+)/([0-9]+)/?$ /products/product-full-view.php?src=$1&id=$2 [L]
RewriteRule ^buy/([a-zA-Z0-9_-]+)/([0-9]+)/?$ /buy/buy-full-view.php?src=$1&id=$2 [L]
Or something to that order anyway.
Note the stub and the [L] each time: the products/ and buy/ avoid that the same URL refers to two different locations, and the [L] (for "Last") tells the rewrite engine to stop processing rules when it gets matched.
If a URL matches the second rule, it also matches the first rule. After applying the first rule, the resulting URL no longer matches the second rule. That's why the second rule is never applied.

mod rewrite exclude all but php

Is it possible to edit htacces in such a way that only the following url is rewritten and the rest isn't?
http://www.example.com/index.php?x=foobar
to
http://www.example.com/foobar/
I want the pages not having x=... as a variable to behave normally
I got the following but that doesn't work
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*)/ index.php?x=$1
RewriteCond $1 !\.(js|ico|gif|jpg|png|css|html|swf|mp3|wav|txt)$
Who can help me?
First off, the RewriteCond must be put before the RewriteRule to which it belongs.
But I think that you need another approach for your case, something like this:
RewriteRule (.*)\.php - [PT,L]
RewriteRule ^(.*)/$ index.php?x=$1
The first rule Passes Through (PT) every PHP page, so the second rule is only applied to all non-PHP requests.
That second rule only applies to a "simple path", no matter if this path has a dot in it or not (e.g. hello.gif/ will match, too).
If this does not work for you, then you might consider one of these points to start further research:
the pattern ([^\.]*) matches everything that does not have a dot in it
see RewriteCond to skip rule if file or directory exists for RewriteConds where the following RewriteRule is only used if the request does not point to an existing file or directory
Hope this helps.

htaccess redirect with php variables ...

I'm using this format in my htaccess to redirect several pages/links:
RewriteEngine On
RewriteRule special.php http://www.mysite.com [R=301]
...
...
RewriteRule http://www.mysite.com/special.php?t=master http://www.mysite.com/index.php?q=former [R=301, L]
I noticed, first, that only the top line is catching anything, and in fact the others, like the bottom line, did nothing until I put in that top line. Any ideas why?
Second, mysite.com/special.php?t=grave is redirected, by the above top line, to mysite.com/?t=grave , thus retaining the variables in the URL. I don't want this, I simply want it to go to mysite.com with no variables. How do I do this?
Thanks,
Derek
First, your first rule catches any URI with special.php in it, even if it is followed by a bunch of characters. To limit it to only and exactly special.php, and to make sure the query string is discarded, change it to
RewriteRule ^special.php$ http://www.mysite.com/? [L, R=301]
Secondly, rewrite rules only match the part after http://www.mysite.com/ (note the last slash) and before the query string (the part after the question mark). So if you change the format of those rules to
RewriteCond %{QUERY_STRING} t=master
RewriteRule ^special.php$ index.php?q=former [R=301, L]
you should be good to go.

.htaccess mod-rewrite conditional statements and sending GET request?

Not necessarily a problem, just something that I am not yet knowledgeable enough to do. I have an .htaccess file that I am using for url rewriting. This is what I have now.
ErrorDocument 404 /inc/error_documents/404.php
ErrorDocument 503 /inc/error_documents/503.php
# For security reasons, Option followsymlinks cannot be overridden.
#Options +FollowSymLinks
Options +SymLinksIfOwnerMatch
RewriteEngine ON
RewriteRule ^home$ /index.php [nc]
RewriteRule ^(about|contact|giving-tree)/?$ /$1.php [nc]
RewriteRule ^giving-tree/([0-9+]?)/?$ giving-tree.php?ageBegin=$1 [nc]
RewriteRule ^giving-tree/([0-9+]?)/([0-9+]?)/?$ giving-tree.php?ageBegin=$1&ageEnd=$2 [nc]
RewriteRule ^giving-tree/([0-9+]?)/([0-9+]?)/([0-9+]?)/?$ giving-tree.php?ageBegin=$1&ageEnd=$2&page=$3 [nc]
What I want to be able to do is make some of the parts in the 3 bottom rules optional. I know that I can accomplish this with RewriteCond, but I'm not sure how. What I need is basically this:
RewriteCond %{HTTP_HOST} ^hearttohandparadise.org/giving-tree
RewriteRule /beginAge-([0-9+]) #make it send GET request with beginAge as the variable
RewriteRule /endAge-([0-9+]) \?beginAge=$1 #make it send GET request with endAge as the variable
etc... etc...
Is there any way to accomplish this just by relying on .htaccess? or am I just fantasizing?
Forgive me is I sound stupid.
No, it's a perfectly valid idea. You'd basically want to allow the user to write the URI in an unstructured manner, without a strict order imposed, right? Like, I could write giving-tree/page-6/endAge-23?
If so, this is what you're looking for:
RewriteRule /beginAge-([0-9]+) giving-tree.php?beginAge=$1 [QSA,NC]
RewriteRule /endAge-([0-9]+) giving-tree.php?endAge=$1 [NC,QSA]
RewriteRule /page-([0-9]+) giving-tree.php?page=$1 [NC,QSA]
You see, if any part of the URI matches the expression "/beginAge-([0-9]+)", it'll be redirected to giving-tree.php?beginAge=$1; the magic is done by the QSA, Query String Append, option, which, well, appends any existing query string to the resulting URI. So as more and more matches are found and more and more GET parameters added, the query string just grows.
If you want a stricter thing, where some parameters are optional, but their order is fixed, then it's uglier by magnitudes:
RewriteRule /(beginAge-)?([0-9]+)/?(endAge-)?([0-9]+)?/?(page-)?([0-9]+)? giving-tree.php?beginAge=$2&endAge=$4&page=$6 [NC]
I just made everything optional by using the ? operator. This one may use some prettifying/restructuring.
(Alternatively, you could just do this:
RewriteRule ^giving-tree/([^/]+)/?$ process.php?params=$1 [nc]
That is, grabbing the entire part of the URI after the giving-tree part, lumping the whole thing into a single parameter, then processing the thing with PHP (as it's somewhat better equipped to string manipulation). But the first version is certainly more elegant.)
By the way, are you sure about the ([0-9+]?) parts? This means "One or no single character, which may be a digit or the plus sign". I think you meant ([0-9]+), i.e. "one or more digit".

Resources