Url management with Yii2 - php

I have a problem with Yii2's urlManager. I have an action with url category/index, where I pass ?par=test as param.
I want to create an alias for my url so that when par is not specified the url will be /test, but when it is specified the url should be /test/some-value. Here is my config for now:
'rules' => [
[
'pattern' => 'test',
'route' => 'category/index',
],
'<subcats: (val|some-value)>' => 'test/<subcats>',

If you need url like category/index/test/some-value. Use that
'category/index/test/<val:\w+>' => 'category/index'
In controller in method index use that:
public function actionIndex($val){
Yii2 automatically provide parameter $val in action.

Related

how to change url name while using resource route in laravel

Normally while using resource route for example like this:
Route::resource('somethings','SomethingsController' );
The url here which is displayed in browser in http://localhost:8000/somthings/create but what want is to display like this:
http://localhost:8000/somthings basically I dont want create in the url.
You can't change URL while using Route::resource(). You'll need to define all routes manually:
Route::get('somethings', 'SomethingsController#createSomething');
https://laravel.com/docs/9.x/controllers#restful-localizing-resource-uris
App\Providers\RouteServiceProvider
file, boot add the following;
public function boot()
{
Route::resourceVerbs([
'create' => 'oluştur',
'edit' => 'düzenle',
]);
// ...
}
To change route names in resource:
Route::resource('somethings', 'SomethingsController', [
'names' => [
'index' => 'somethings.index',
'store' => 'somethings.store',
...
]
]);

How to find a record using a field other than id in Yii 2

I have the following code where I want to find a model using a field called link instead of id. However, it doesn't seem to produce any results. Where could I be getting it wrong? It returns 404
public function actionView($link)
{
$model = News::find()->where(['link'=>$link])->all();
return $this->render('view', [
'model' => $model,
]);
}
NB: in the search model, I have tried adding this:
$query->andFilterWhere([
'id' => $this->id,
'link'=>$this->link,
'category' => $this->category,
'date' => $this->date,
'userid' => $this->userid,
'featured' => $this->featured,
]);
If you want a single model you need one() and not all()
public function actionView($link)
{
$model = News::find()->where(['link'=>$link])->one();
return $this->render('view', [
'model' => $model,
]);
}
With one() method you retrive just a model and in your $model you have the data you need ..
If you sue all() lie you did you retrive a collection of models and for accessing a single model you must set a proper index eg:
$my_model = $model[0];
In UrlManager config you propably have:
'<controller>/<action>/<id:\d+>' => '<controller>/<action>',
It means default rewrite rules use id as param and it has to be digit, so you can't use controller/view/link. Just to be sure, change action name from actionView to actionTest and then call URL controller/test?link=linklink.
Other solution is to use URL like this: controller/view?link=linklink
The problem is in your url
case 1)
http://localhost/projectName/backend/web/controllerName/actionName/username/rushil
Gives output : Not Found (#404)
case 2)
http://localhost/projectName/backend/web/controllerName/actionName/rushil
Gives output : Not Found (#404)
case 3)
http://localhost/projectName/backend/web/controllerName/actionName?username=rushil
this will work.
Solution : check your url and pass link parameter in url as shown in case 3
404 means your action was not found by url manager. link parameter must be in the url (http://yourapp/controller/view?link=something) because you definded it as actionView($link)
Requesting http://yourapp/controller/view will give you 404 error.
For anyone who may encounter such an error, the problem is after using pretty urls, you need to add rules to map the url format.
C:\xampp\htdocs\your_project\frontend\config\main.php under urlManager add the rules like so:
'urlManager' => [
'class' => 'yii\web\UrlManager',
// Disable index.php
'showScriptName' => false,
// Disable r= routes
'enablePrettyUrl' => true,
'rules' => array(
'<controller:\w+>/<id:\d+>' => 'news/view',
'<controller:\w+>/<link>' => 'news/latestnews', // This is required for $link parameter
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>/<link>' => 'news/latestnews',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
],
],

Yii2 url rule for module and parameters

I am trying to configure Yii2 url manager in a manner that if a controller name is skipped in url it should call the default controller for action. I have managed to achieve this without action parameter. But got stuck when using parameters in action name.
Here is my route config:
return [
'catalog/category/<alias:[\w-]+>' => 'catalog/default/category',
'catalog/<action:\w+>' => 'catalog/default/<action>',
];
Controller File:
namespace app\modules\catalog\controllers;
use yii\base\Controller;
use app\modules\catalog\models\Categories;
class DefaultController extends Controller
{
public function actionShopbydepartment()
{
$data['categories'] = Categories::findParentSubHierarchy();
return $this->renderPartial('shopbydepartment', $data);
}
public function actionCategory($alias = null)
{
die(var_dump($alias));
$data['category'] = Categories::findCategoryBySlug($alias);
return $this->render('category', $data);
}
}
when I access the following url it loads perfectly.
http://domain.com/index.php/catalog/shopbydepartment
But when i access the below url it called the right function but did not pass the $alias value:
http://domain.com/index.php/catalog/category/appliances
UPDATE:
I have used the following approach for module wise url rules declaration:
https://stackoverflow.com/a/27959286/1232366
Here is what i have in the main config file:
'rules' => [
[
'pattern' => 'admin/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<controller>/<action>'
],
[
'pattern' => 'admin/<module:\w+>/<controller:\w+>/<action:[\w-]+>/<id:\d+>',
'route' => 'admin/<module>/<controller>/<action>'
],
],
the admin is working fine and this is my first module so rest of the rules are mentioned already
Well just to help other fellows I have retrieve the value of $alias using the following approach:
$alias = \Yii::$app->request->get('alias');
But definitely this is not an accurate answer of the question. I still didn't know what i am doing wrong that i didn't get the value using the approach mentioned in question.
It wirk!
[
'name' => 'lang_country_seller_catalog',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/<module>/<controller>/<action>',
'route' => 'seller/catalog/<module>/<controller>/<action>',
],
[
'name' => 'lang_country_seller_catalog_attributes',
'pattern' => '<lang:\w+>-<country:\w+>/seller/catalog/attributes/<module>',
'route' => 'seller/catalog/attributes/<module>',
],

How to access defined URL in Yii2

I have controller UserController and action actionAjax. I access by Chrome with below URL and it is working normally.
index.php?r=user/ajax
Now I define new action with named actionAjaxUser, still using Chrome to access URL index.php?user/ajaxUser
Then 404 returned.
What should I do to getting content of actionAjaxUser?
add for each additional uppercase Letter after "action" a "-" so in your case
index.php?r=user/ajax-user
So if you would have an action like actionTest1Test2Test3 the url would be controllername/test1-test2-test3.
Be aware that if you are using access rules you also have to use the "url" path.
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['test1-test2-test3'],
'allow' => true,
'roles' => ['#'],
],
],
],
];
The same Naming scheme is btw. also used for Controllers. E.g. if your Controller is named Test1Test2Controller the view folder name would be test1-test2.
Hope this clarifies this for you.

Is it posible to create a urlManager Rule which preloads an object based on ID?

Working with Yii 2.0.4, I'm trying to use urlManager Rule to preload an object based on a given ID in the URL.
config/web.php
'components' => [
'urlManager' => [
[
'pattern' => 'view/<id:\d+>',
'route' => 'site/view',
'defaults' => ['client' => Client::findOne($id)],
],
[
'pattern' => 'update/<id:\d+>',
'route' => 'site/update',
'defaults' => ['client' => Client::findOne($id)],
],
]
]
If this works, it will not be necessary to manually find and object each time, for some CRUD actions:
class SiteController extends Controller {
public function actionView() {
// Using the $client from the urlManager Rule
// Instead of using $client = Client::findOne($id);
return $this->render('view', ['client' => $client]);
}
public function actionUpdate() {
// Using $client from urlManager Rule
// Instead of using $client = Client::findOne($id);
if ($client->load(Yii::$app->request->post()) && $client->save()) {
return $this->redirect(['view', 'id' => $client->id]);
} else {
return $this->render('edit', ['client' => $client]);
}
}
}
NOTE: The above snippets are not working. They're the idea of what I want to get
Is it possible? Is there any way to achieve this?
If you look closer: nothing actually changes. You still call Client::findOne($id); but now doing it in an unexpected and inappropriate place, and if you look at the comment about default parameter it says:
array the default GET parameters (name => value) that this rule provides.
When this rule is used to parse the incoming request, the values declared in this property will be injected into $_GET.
default parameter is needed when you want to specify some $_GET parameters for your rule. E.g.
[
'pattern' => '/',
'route' => 'article/view',
'defaults' => ['id' => 1],
]
Here we specify article with id = 1 as default article when you open main page of site e.g. http://example.com/ will be handled as http://example.com/article/view?id=1
I can suggest to you add property clientModel in to your controller and then in beforeAction() method check if its update or view action then set
$this->clientModel = Client::findOne($id);
and in your action:
return $this->render('view', ['client' => $this->clientModel]);

Categories