Yii2 Nav widget doesnt support routes with baseUrl - yii

1) I have my Yii2 in subfilder, so all my link starts from Yii/, like http:/localhost/Yii/settings/usertype-activitytype/type/3
2) request component config
'request' => [
'cookieValidationKey' => 'somecookiekey',
'baseUrl' => '/Yii',
],
3) Trying to build Menu, current route is http:/localhost/Yii/settings/usertype-activitytype/type/1 the 1 is id in route, and I should specify current route as Yii::$app->request->pathInfo for Nav widget
Attempt 1 - no bracets as string NOT FIND ACTIVE ELEMENT
Nav::widget([
'items' => array_map(function($userType) {
return [
'label' => $userType->name,
'url' => Url::current(['id' => $userType->id]),
];
}, $userTypes),
'route' => Yii::$app->request->pathInfo,
'options' => ['class' =>'nav-pills'],
]);
Attempt 2 - use bracets as route NOT FIND ACTIVE ELEMENT
Nav::widget([
'items' => array_map(function($userType) {
return [
'label' => $userType->name,
'url' => [Url::current(['id' => $userType->id])]
];
}, $userTypes),
'route' => Yii::$app->request->pathInfo,
'options' => ['class' =>'nav-pills'],
]);
Attempt 3 - remove baseUrl from generated route FIND ACTIVE ELEMENT !!!
Nav::widget([
'items' => array_map(function($userType) {
return [
'label' => $userType->name,
'url' => [str_replace('Yii/', '', Url::current(['id' => $userType->id]))]
];
}, $userTypes),
'route' => Yii::$app->request->pathInfo,
'options' => ['class' =>'nav-pills'],
]);
So you should notice I have to use dirty hack to force Nav work with generated Url, it seems very unconvient.
The question is - is there are ways to force NAV widget to recognize current active item ?

If you want buil an url based on your param you should use Url::to()as
'url' => Url::to(your-controller/your-view', ['id' => $userType->id]),
so accessing the view type for controller usertype-activitytype
'url' => Url::to('usertype-activitytype/type', ['id' => $userType->id]),
current Creates a URL by using the current route and the GET parameters.
and remember that
By Design UrlManager always prepends base URL to the generated URLs.
By default base URL is determined based on the location of entry
script. If you want to customize this, you should configure the
baseUrl property of UrlManager.
Looking to your comment the url is correcly formed .. then if you need http:/localhost/Yii instead of Yii then you can:
don't set so the localhost ... url is atomatically created
OR add the proper base url configureation as http:/localhost/Yii/ in config /main and remember that you can use main.php and main-local.php for manage different congiguration

Related

Cakephp 3 Authentication plugin, login URL did not match

I want to use the Authentication plugin for CakePHP 3.8 and I'm having problems that are not in documentation.
After follow Getting Started (https://book.cakephp.org/authentication/1/en/index.html) I have one question.
Originally $fields were specified to change username and password relation in real database, same that Auth component, and login URL is where login form si loaded.
First, in getting started or any part of documentation doesn't says about a login view (form), so, like old Auth Component I created this to Users/login.ctp
<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your email and password') ?></legend>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
My code in Application.php includes this (with its respective uses and implements):
public function getAuthenticationService(ServerRequestInterface $request, ResponseInterface $response)
{
$service = new AuthenticationService();
$fields = [
'username' => 'email',
'password' => 'password'
];
// Load identifiers
$service->loadIdentifier('Authentication.Password', compact('fields'));
// Load the authenticators, you want session first
$service->loadAuthenticator('Authentication.Session');
$service->loadAuthenticator('Authentication.Form', [
'fields' => $fields,
'loginUrl' => '/users/login'
]);
return $service;
}
But when I try to login, I have this error, after var_dump in login.ctp I get this:
object(Authentication\Authenticator\Result)[124]
protected '_status' => string 'FAILURE_OTHER' (length=13)
protected '_data' => null
protected '_errors' =>
array (size=1)
0 => string 'Login URL `http://localhost/users/login` did not match `/users/login`.' (length=70)
If I comment 'loginUrl' => '/users/login' line, then login works fine.
Additional notes:
- I've tested with hashed and textplane passwords, same results.
- I've added $this->Authentication->allowUnauthenticated(['view', 'index', 'login', 'add']); in beforeFilter to access login.
- It's a clean cakephp 3.8 install, only database is the same for tests.
- I've added Crud only with cake console.
I would like to learn more about that loginURL, I should include some uses in UsersController? What causes this error?
Thank you
The error messages is currently a little misleading, as it doesn't show you the possible base directory, which is the actual issue that you are experiencing. I've proposed a fix for that, which may make into the next release.
When your application lives in a subdirectory, you need to make sure that your login URL configuration takes that into account, that is by either passing the URL including the base directory, which you could do either manually:
'loginUrl' => '/myapp/users/login'
or by using the router:
'loginUrl' => \Cake\Routing\Router::url('/users/login')
'loginUrl' => \Cake\Routing\Router::url([
'plugin' => null,
'prefix' => null,
'controller' => 'Users',
'action' => 'login'
])
Another option would be to use the routes based URL checker, which can be configured via the form authenticators urlChecker option, then you can define the login URL using URL arrays, without having to use the router:
'urlChecker' => 'Authentication.CakeRouter',
'loginUrl' => [
'plugin' => null,
'prefix' => null,
'controller' => 'Users',
'action' => 'login'
]
See also:
Authentication Cookbook > Authenticators > Form
Authentication Cookbook > URL Checkers

How to specify new subdirectory in routes for Yii 2 module?

I'm using Yii 2 and building a RESTful API inside a Yii 2 module called apiv1.
The file config.php for the module apiv1 looks like this:
// ...
urlManager' => [
// ...
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'likes',
],
],
],
];
For instance, GET /apiv1/likes works, but I'd like to set up a route to handle GET /api/v1/likes. How can this be done either individually or for the entire module as a general route from api/v1 to apiv1?
You can use the prefix attribute to customize your rest/UrlRule routes.
E.g., for your case, you should be able to do:
[
'class' => 'yii\rest\UrlRule',
'controller' => 'likes',
'prefix' => 'api/v1',
]
For more info, you can see the REST routing guide and yii-rest-rule API docs - in particular, see the $patterns and $extraPatterns properties for additional configuration options.

Routing in module doesn't work Yii 2

I am new in Yii 2 and my problem is about routing inside a module.
I have a module in my app which is a profile cabinet both for users and admins. I created a CabinetController instead of DefaultController and also I created a AdminController and UserController.
What I want? I want this CabinetController received request and forward it to either AdminController or UserController after verify wether the user is admin or not.
In config file I set a default route for module as "cabinet"(as I understand this is a name for default controller). And in "rules" part of UrlManager I wrote following:
'modules' => [
'cabinet' => [
'class' => 'app\modules\cabinet\Module',
'defaultRoute' => 'cabinet'
],
'utility' => [
'class' => 'c006\utility\migration\Module',
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
'<_c:\w+>/' => '<_c>/',
'<_c:[\w\-]+>/<_a:\w+>' => '<_c>/<_a>',
'<_m:cabinet>/<_a:\w+>' => '<_a>',
],
],
If I go to "my-site.com/cabinet" it works fine and open "admin/index" because I made it to redirest this request to AdminController/actionIndex, but once I go to somewhere like "my-site.com/cabinet/users" it respond with 404 NotFound. I open the loger and see: exception 'yii\base\InvalidRouteException' with message 'Unable to resolve the request "cabinet/desktop"
This is my CabinetController and the way I forward requests to Admin/UserController:
public function init()
{
parent::init();
$this->user = $this->findModel();
$this->controllerToUse = $this->user->isAdmin() ? 'admin' : 'user';
}
public function actionIndex()
{
return $this->module->runAction($this->controllerToUse . '/' . $this->action->id);
}
If I change defaultAction in CabinetController it run this action normally as expected. Or if I go to "my-site.com/cabinet/admin/users" again it works good, because it found a controller in the url(as I think).
Routing can be a bit tricky in Yii2, it follows a few rules you need to understand which can be found here
But if i understand you correctly Admin/UserController is part of the Cabinet module? and you want Yii to route /cabinet/users to /cabinet/admin/users
You'll need to add some rules in your UrlManager see Rules
Example:
'rules' => [
'<module:cabinet>/<action:\w+>' => '<module>/admin/<action>',
],
Hope it helps

how change items in view of admin panel yii

I create admin panel in yii1 via CRUD. In list section display news with status (1 and 2). But i need display "Publish" and "Archive" instead 1 and 2. I did this in view but this way wrong.How i can do it?
You can try change zii.widgets.grid.CGridView if you use it.
Something like this:
'columns' => [
[
'type' => 'html',
'name' => 'status',
'value' => '"<div class=helper>". (1 === $data->status) ? 'Archive' : 'Publish' ."</div>"',
'htmlOptions' => ['data-label' => 'Status']
],

Beautifying URLs in Yii

I have following file structure
As default the url created for accessing the module content is for example
http://127.0.0.1/tmc/user/default/viewMessage
and for other controller it comes out to be
http://127.0.0.1/tmc/user/booking/index
The problem is I want to write a rule in my urlManager so that both controllers remain accessible AND i do not see default word in url as in first example.
However if i write following rules I am able to eliminate the default word but now other controllers in same module wont work. any help in this regard is appreciated
'<module:\w+>/<action:\w+>/<id:(.*?)>' => '<module>/default/<action>/<id>',
'<module:\w+>/<action:\w+>' => '<module>/default/<action>',
My current Url Manager is as follow
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'/' => 'site/index',
'login' => 'site/login',
'user' => 'user/default/',
'<view:[a-zA-Z0-9-]+>/' => 'site/page',
),
),
Follow this Link for config settings
Refer this Link
//inside protected/modules/admin/AdminModule.php
class AdminModule extends CWebModule
{
//goes to TaskController instead of DefaultController
public $defaultController = 'Task';
...
Now your Yii application will routes to the “TaskController” if you request
index.php?r=admin
//same as requesting
index.php?r=admin/task