Cannot route to custom action in Yii2 controller - php

I am building a RESTful API with Yii2 (advanced) and endpoints are working as expected apart from a custom one I need.
My urlManagerlooks like:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' =>
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/step', 'pluralize' => false],
],
If I add a custom action into the StepController like so it will work just fine - Calling with http://example.com/api/v1/step/test
public function actionTest()
However if I want to pass an ID in through the path I will receive a 404 error - http://example.com/api/v1/step/test/1
public function actionTest($id)
Is there something I'm missing?
Edit: Adding notes that may help others.
My example above was simplified but what I wanted my URL to look like was like http://example.com/api/v1/step/test-by-foobar/1 with the called method to be public function actionTestByFoobar($id). However to get this to work you have to set the urlManager rule like the following which I didn't find obvious:
'api/v1/step/test-by-foobar/1' => 'api/v1/step/test-by-foobar',
Notice that the value is hyphenated, not in camel-case.

With your code you can pass an id like this :
http://example.com/api/v1/step/test?id=1
But if you want to do it like this:
http://example.com/api/v1/step/test/1
You should rewrite the url like below:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => 'api/v1/step',
'pluralize' => false
],
/* You are missing this line below */
'api/v1/step/test/<id:\d+>' => 'api/v1/step/test'
]
],

Related

YII2 sef urls construction

I have catalogue with products. Urls for products looks like this domain.com/adv?id=14792.
I want to beautify urls like this domain.com/adv/14792.
In web.php I tried to like this
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
'adv/<id:\d+>' => 'site/adv',
'<alias:[\w-]+>' => 'site/<alias>',
],
],
and there is no result.
I tried another variant in rules block:
'rules' => [
'adv/<id:\d+>' => 'adv',
'<alias:[\w-]+>' => 'site/<alias>',
],
and urls start to look like I want. But on this link I get 404 page.
Please use action with adv so that it work.
'rules' => [
'adv/<id:\d+>' => 'adv/<add some action here>',
'<alias:[\w-]+>' => 'site/<alias>',
],
I solved my problem by myself. This is my urlmanager module now:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'adv/<id:\d+>' => 'site/adv',
'<alias:[\w-]+>' => 'site/<alias>',
'<controller:\w+>/<action:\w+>/' => '<controller>/<action>',
],
this construction build url from https://example.com/adv?id=123456 to https://example.com/adv/123456.
In view link build with
Html::a($insideEl,Url::to(['adv','id' => $ladvert->id]))
and in siteController action is
actionAdv($id)
Thanx.

Add language to url in Yii2

I have following url for example:
http://mywebsite.com/testing/test
And I want it to be something like this depending on the current language:
http://mywebsite.com/en/testing/test
I have language stored in: Yii::$app->language
I tried to modify my URLManager (/config/web.php), but it doesn't work for me.
'urlManager' => [
'class' => 'yii\web\UrlManager',
'showScriptName' => false,
'enablePrettyUrl' => true,
'rules' => [
'/login' => 'site/login',
'/logout' => 'site/logout',
Yii::$app->language.'/'.'<controller:\w+>s'=>'<controller>/index',
Yii::$app->language.'/'.'<controller:\w+>/<id:\d+>/<title:\w+>'=>'<controller>/view',
Yii::$app->language.'/'.'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
Yii::$app->language.'/'.'<controller:\w+>/<action:\w+>/<id:\d+>/*'=>'<controller>/<action>',
],
],
Can You help me?
I found an extension. Even if you don't want to use it, you can look into it’s code to get an idea how it works. (Changing patterns / routing / etc.)
https://github.com/codemix/yii2-localeurls

How to fix 'Static page in sub-directory" issue in Yii2

I have setup my Yii2 powered website but I will like to get some of my static pages in sub-directories and then display the name of the sub-directory in the url. For example, have in site/hotel/pacific.php and site/mini-rooms/standard.php and then access them using xyz.com/hotel/pacific and xyz.com/mini-rooms/standard.
I have tried to follow some examples online but I am not sure why the are not working. Some of the examples are also for yii and not yii2.
Here is what I did:
In the SiteController.php, I had created a static page before using the code below and I can visit it atxyz.com/hotel/pacific. But now I am moving it into a subdirectory hotel. It was formerly inside the views/site folder:
public function actionPacific()
{
return $this->render('pacific');
}
I then created a folder name pages inside the view folder. Inside the pages folder, I created hotel folder and inside hotel folder I placed pacific.php file so I have views/site/pages/hotel/pacific.php
Also in the SiteController.php, I added this:
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
'page' => [
'class'=>'CViewAction',
],
'hotels' => [
'class'=>'CViewAction',
'basePath' => 'pages/hotels'
],
];
}
I then configure my config/web.php by adding the code below:
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing'=>false,
'rules' => [
'<alias:[\w\-]+>' => 'site/<alias>',
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
],
],
I got 404 error when I visit xyz.com/hotel/pacific.
How can I properly do this for both examples - xyz.com/hotel/pacific and xyz.com/mini-rooms/standard.
What I understood that you are mixing Yii 1 & 2 as CWebView is used in Yii1 and not Yii2. So what you need is probably yii\web\ViewAction, which will represent a single action. There might be better answers someone else could suggest.
So if you have a directory.
views/site/hotel/pacific.php
views/site/hotel/five-star.php
And you want to access the pacific.php view by typing in the URL xyz.com/hotel/pacific and five-star.php with xyz.com/hotel/five-star.
Then you should configure them like below
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction'
],
'pacific' => [
'class' => 'yii\web\ViewAction',
'defaultView' => 'pacific',
'viewPrefix' => 'hotel'
],
'five-star' => [
'class' => 'yii\web\ViewAction',
'defaultView' => 'five-star',
'viewPrefix' => 'hotel'
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null
]
];
}
and then update the urlManager like below
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing'=>false,
'rules' => [
'/' => 'site/index',
'<alias:[\w\-]+>' => 'site/<alias>',
'hotel/<alias:[\w\-]+>' => 'site/<alias>',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>'
]
],
Now if you type in the browser xyz.com/hotel/pacific or xyz.com/hotel/five-star it will show you the corresponding views.
Hope it solves your problem.
I decided to create HotelController.php inside the controller folder and then create hotel folder under views folder. I then added pacific.php inside the hotel folder and add the action code inside HotelController.php as below.
public function actionPacific()
{
return $this->render('pacific');
}
It works as I wanted although I am not sure if there are better alternatives. I removed the rules in the url manager as I did not need them now. I only had to just go to mysite.com/hotel/pacific to display the page. I can create as many page as I need inside the folder and just add their action code.

Yii2 rest api rewrite rules

This is how my url manager looks like:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => 'v1/user',
'extraPatterns' => [
'GET account' => 'account',
],
]
],
]
In order to make this call I can access this url:
localhost/project/api/web/v1/user/account
What I need to do is to remove controller name from url(user). I need to call the api at this url:
localhost/project/api/web/v1/account.
How can I achieve this? I tried a lot of tricks but none worked.
Thanks for your help.
You need to add following expression under rules
'v1/account' => 'v1/user/account',

urlmanager with modules not working in yii2.0

This regarding module creation inside backend folder.Example i have created a module name as "api". And also sccessfully created controller for that modules.
here is my urlmanager code:
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'rules' => [
'<module:\w+>/<controller:\w+>/<action:\w+>'=>'<module>/<controller>/<action>',
'<module:\w+><controller:\w+>/<action:update|delete>/<id:\d+>' => '<module>/<controller>/<action>',
],
]
when i access url with respect to module as "api" , controller as "country" and action as "create"
http://local2host.com/bootstrap/backend/web/index.php/api/country/create
it showing 404 Not Found error
Where i am going wrong?
The second rule will never work, Also you do not have to define the rules and the normal ones will work. So this
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
],
will make this link /website.com/core/contact/index work just fine.
But I am not sure why your route is not catching the first rule... strange. It should.
Better late then never.
For make module works you need to append it in config:
'modules' => [
......
'modulename' => [
'class' => 'app\modules\modulename\Module',
],
......
],

Categories