Yii seo url rewrite urlManager and .htaccess - .htaccess

i'm involved with the url seo in yii webapp. I can not achieve the desired result.
First of all, the website is multilanguage. I've created a language switcher, i pass the "lang" parameter as GET value in the url.
Then i've followed the wiki at this url:
http://www.yiiframework.com/wiki/294/seo-conform-multilingual-urls-language-selector-widget-i18n/
Step 1) I've create the urlManager class
Step 2) Edit my controller
Step 5) Edit my config file
For the step 5 i've use the following code:
'urlManager' => array(
'class' => 'application.components.UrlManager',
'urlFormat' => 'path',
'showScriptName' => false,
'urlSuffix'=>"/",
'rules' => array(
'<lang:(de|it|en|fr|es)>'=>'',
'<lang:(de|it|en|fr|es)>'=>'site/index',
'<lang:(de|it|en|fr|es)>/<action:(!index)>/*' => 'site/<action>',
'<lang:(de|it|en|fr|es)>/<controller:\w+>/<id:\d+>' => '<controller>/view',
'<lang:(de|it|en|fr|es)>/<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<lang:(de|it|en|fr|es)>/<controller:\w+>/<action:\w+>/*' => '<controller>/<action>',
),
),
And my .htaccess is the same as yii default .htaccess
<Files .htaccess>
order allow,deny
deny from all
</Files>
Options All -Indexes
I've changed nothing.
Now, i've tried different rules for urlManager and tried to add other rules to htacces, without success.
My problem is that, some of page break with a 404 error, same thing for resources such as image or script. If i check the resources requested url from element inspector, i see that the requested url is rewrite as for the url of the site (is that correct behavior?)
I've also tried to put the entire project under a root subfolder, to create a test enviroment different from production, the result is worse, due to the subfolder.
In addition if i click on home link, the system redirect me to www.mysite.com/lang/en
In addition i've added a behavior that retrieve language based on ip or set statically one, so at the end of request processing, i always have a language code to put as get parameter.
(The GET language url parameter is called "lang")
What i need is:
if someone visit the main url - www.mysite.com - i need to add the language in url, so i can have different url based on language in this manner: www.mysite.com/it/ , www.mysite.com/en/ etc etc.
same as above for the url create like this Yii::app()->createUrl('')
if someone visit www.mysite.com/index.php?r=site/index same as above and remove index.php
remove index.php and site in all situation
any kind of url always end with / character (also to avoid duplicate content, for this i've added 'urlSuffix' => "/")
for the other controller i need to delete view action (but mantaining the other) - and when is present made "id" as part of url in this way:
[www.mysite.com/controller/action/id/1?here-other-get-params] OR
[www.mysite.com/controller/id/1?other-params] -> when the action is view
Please, can someone provide the step by step procedure of what i've to do?
Thank you
Regards,
Francesco

Have you tried to add a trailing slash to the index.php in .htaccess and did you set RewriteBase ?
With xampp on Windows 8 with Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7 the following should work:
.htaccess
RewriteEngine on
#LOCAL
RewriteBase /myDir/subDir/
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
# otherwise forward it to index.php
RewriteRule . /index.php
AddDefaultCharset utf-8
And in config/main.php
'urlManager' => array(
'class' => 'application.components.UrlManager', // which refers to UrlManager.php
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'login' => 'site/login',
'<language:(de|en|fr|es)>/' => 'content/index',
'<language:(de|en|fr|es)>/<action:(contact|login|logout)>/*' => 'site/<action>',
'<language:(de|en|fr|es)>/<controller:\w+>/<id:\d+>' => '<controller>/view',
'<language:(de|en|fr|es)>/<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<language:(de|en|fr|es)>/<controller:\w+>/<action:\w+>/*' => '<controller>/<action>',
'<language:(de|en|fr|es)>/<module:\w+>/<controller:\w+>/<action:\w+>/*' => '<module>/<controller>/<action>',
),
),
and /protected/components/UrlManager.php
<?php
class UrlManager extends CUrlManager
{
public function createUrl($route,$params=array(),$ampersand='&')
{
if (!isset($params['language'])) {
if (Yii::app()->user->hasState('language'))
Yii::app()->language = Yii::app()->user->getState('language');
else if(isset(Yii::app()->request->cookies['language']))
Yii::app()->language = Yii::app()->request->cookies['language']->value;
$params['language']=Yii::app()->language;
}
return parent::createUrl($route, $params, $ampersand);
}
}
and in httpd.conf
<Directory "C:/Users/someuser/htdocs">
Options Indexes FollowSymLinks MultiViews Includes ExecCGI
AllowOverride All
Order Allow,Deny
Allow from all
Require all granted
</Directory>

Related

.htaccess url rewrite with get parameters

I have an issue with my htaccess that will make me completely crazy.
I would like to replace event.php?id=158 by event/158
and event.php?id=158&display=documents by event/158/documents
I have found lot's of example doing this but it doesn't works in case and I do not understand why.
If I my rule is
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^event([0-9]+)$ event.php?id=$1 [L]
Then the id paramter is in dump($_REQUEST)
Array ( [id] => 158 [SERVERID94994] => 134038 [PHPSESSID] => 70ed00f7c3854afa31a0d8d5d4a02840 )
But with
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^event/([0-9]+)$ event.php?id=$1 [L]
Then id parameter is no more available in $_REQUEST
Array ( [SERVERID94994] => 134038 [PHPSESSID] => 70ed00f7c3854afa31a0d8d5d4a02840 )
=> Missing id
Please can you explain me what's wrong with the second rule?
Thanks
Add this to disable MultiViews:
Options -MultiViews
The Apache docs on mod_negotiation, describes what the Multiviews Option does, when enabled:
If the
server receives a request for /some/dir/foo and /some/dir/foo does not
exist, then the server reads the directory looking for all files named
foo.*, and effectively fakes up a type map which names all those
files, assigning them the same media types and content-encodings it
would have if the client had asked for one of them by name. It then
chooses the best match to the client's requirements, and returns that
document.
Use:
options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteRule ^event/([0-9]+)$ event.php?id=$1 [L]

Usernames as subdomain

I have a multi-user website which generates user profiles.
By default, the profiles as set to the users' id, e.g. mysite.com/userid
I'd like to be able to change that to the username instead, and place it on the subdomain, e.g. username.mysite.com
Both the id and username are unique in mysql so there will be no duplicate issues.
But I'm struggling to find a way to do this.
I consulted this article: How to let PHP to create subdomain automatically for each user?
Which gave me some idea on how to start, but technically I'm lost.
I added the subdomain *.mysite.com, and tried the following in my .htaccess file:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^a-zA-Z0-9-]*)$ profile/?id=$1
RewriteCond %{HTTP_HOST} ^(^.*)\.mysite.com
RewriteRule (.*) profile/?id=%1
Where "mysite.com" is my actual site. But it produced 404 errors.
Inside my index.php is the following line for seo profile pages:
$router->map(get_option('profile-seo-url','/profile/:name/:id/:section'), 'profile', array('methods' => 'GET,PUT,POST', 'filters' => array('id' => '(\d+)','section' => '(.*)')));
Is this overriding the htaccess file?

How to Configure yii URL manager for subdomain

Perhaps this question has already been asked somewhere, but I couldn't find anything suitable for my problem.
I'm creating a website using yii and its URL manager. In my localhost, the URL manager works perfectly fine. But the problem arise after I upload it to a server with subdomain. The domain and subdomain should be http://tokoandhika.mauinimauitu.com.
In my localhost, http://localhost/tokoandhika/catalog/category1 works fine. It will access actionIndex function in CatalogController.php. But if I access http://tokoandhika.mauinimauitu.com/catalog/category1, it will prompted Internal Server Error (PHP Error 500).
What could have gone wrong? Do I need to edit the htaccess file? Or do I need to add more rules for this? Any helpful advice would be much appreciated.
Below is my rules for the URL manager:
'rules' => array(
'category/<slug:[a-zA-Z0-9-]+>' => 'category/index',
'page/<slug:[a-zA-Z0-9-]+>' => 'site/page/index',
'gii' => 'gii/default',
'gii/<controller:\w+>/<id:\d+>' => 'gii/<controller>/view',
'gii/<controller:\w+>/<action:\w+>/<id:\d+>' => 'gii/<controller>/<action>',
'gii/<controller:\w+>/<action:\w+>' => 'gii/<controller>/<action>',
'gii/<controller:\w+>/<action:\w+>/id/<id:\w->' => 'gii/<controller>/<action>/id/<id>',
'catalog/addtocart/' => 'catalog/addtocart',
'catalog/detail/<slug:[a-zA-Z0-9-]+>' => 'catalog/detail',
'catalog/<cat:[a-zA-Z0-9-]+>/<subcat:[a-zA-Z0-9-]+>' => 'catalog/index',
'catalog/<cat:[a-zA-Z0-9-]+>' => 'catalog/index',
),
and here is my htaccess:
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php

Kohana 3.3 Routing Issue

This route I am using works perfectly on local MAMP server, but not Dreamhost or HostPapa. I figured it was just a case sensitivity issue, but from what I can tell everything looks fine.
Error Message
Kohana_HTTP_Exception [ 404 ]: The requested URL panel/asset/warranty/edit was not found on this server.
Route:
Route::set('panel/asset', '<directory>(/<controller>(/<action>(/<id>)))',
array(
'directory' => 'panel/asset',
'controller' => 'warranty',
))
->defaults(array(
'action' => 'edit',
));
Controller: Controller/Panel/Asset/Warranty.php
class Controller_Panel_Asset_Warranty extends Controller_Site_AdminTemplate
.htaccess
# Turn on URL rewriting
RewriteEngine On
Options -MultiViews
# Installation directory
RewriteBase /
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
SetEnv KOHANA_ENV DEVELOPMENT
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Required for dreamhost
RewriteCond $1 !^(index\.php|public|user_guide|robots\.txt)
RewriteRule .* index.php?$0 [PT,L,QSA]
Am I missing something obvious? Routing always gives me such grief... /annoyed
If you want a parameter to be a hard-coded string, do not put it in the regex array. Only use the regex array when you actually use some regex feature in the values.
This would be better. You could use the regex array to make sure id are digits, which is a valid reason to use it.
Route::set('panel/asset', 'panel/asset(/warranty(/<action>(/<id>)))')
->defaults(array(
'directory' => 'panel/asset',
'controller' => 'warranty',
'action' => 'edit',
));
This won't help you with the problem at hand though, if the URI haden't matched a route the exception read Kohana_HTTP_Exception [ 404 ]:Unable to find a route to match the URI: panel/asset/warranty/edit.
The exception is telling you Kohana is looking for a route to match the URI panel/asset/warranty/edit I assume that is what you want. So the problem would be somewhere in your application, not the .htaccess file.
There are only two methods which have the following block of code in it.
throw HTTP_Exception::factory(404,
'The requested URL :uri was not found on this server.',
array(':uri' => $this->request->uri())
)->request($this->request);
Those methods are Request_Client_Internal::execute_request() and Controller::execute().
Have you placed some kind of debug statement in Controller/Panel/Asset/Warranty.php to see if it is found and executed? Because while reproducing I somehow the file was executed but class_exists('Controller_Panel_Asset_Warranty', FALSE) returned FALSE. When I copied the class name from your question and replaced the one I typed myself with it it suddenly worked. If I undid the paste it stopped working again. I checked letter for letter and my editor showed me the exact same thing before and after.
I hope this helps you narrow it down.

Load default action and controller if none were found

I'm not sure if it's possible, but what i need is to load default controller and action if specified controller has not been found from the url, so let's say if i have this url:
http://mywebsite.com/john
It would have to call user controller and selected_user action,
And if i have url http://mywebsite.com/pages/profile
it would have to call pages controller and profile action because both has been specified and found
Is there a way to do it?
I am using Kohana 3.2
EDIT Here is my htaccess:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /ep/
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
/ep is my directory in htdocs also i did set 'base_url' => '/ep/', in my bootstrap as well
Assuming mod_rewriting is enabled and the .htaccess file is configured correctly. All you need to do is specify a new route within the bootstrap, after the current default one.
For example:
<?php
Route::set('default', '(<controller>(/<action>(/<stuff>)))', array('stuff' => '.*'))
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
/** Set a new route for the users **/
Route::set(
"users", "<name>", array("name" => ".*")
)->defaults(array(
'controller' => 'users',
'action' => 'selected_user'
));
/** Within the selected_user method you can then check the request for the "name"
validate the user parameter (parhaps against the db) and then again route the correct
pages/profile if found
e.g.
**/
$username = $this->request->param('name');
if ($username == "alexp") {
/** reroute to the users/profile controller with data **/
}
?>
Edit: also I forgot to mention that the above routes will be called for anything after the base Uri so "http://mysite.com/john" and "http://mysite.com/89s88" will also try to use that route. You could imagine allot of routes being needed over time, so best at least stick to a minimum of /controller/action varieties or you may other wise find yourself with some complicated regex in the routes where it is unneeded.

Resources