yii2 redirect from custom module to base controller - redirect

I use dektrium user registration form.
registration link generates domain.com/user/register link
but it's not base user model, this module is located inside vendor/dektrium folder.
Now in base controllers folder I have UsersController with view action.
and after finishing registration I want to start view action of UsersController to view users page.
This is registration module code
public function actionRegister()
{
if (!$this->module->enableRegistration) {
throw new NotFoundHttpException;
}
$model = $this->module->manager->createRegistrationForm();
if ($model->load(\Yii::$app->request->post()) && $model->register()) {
return $this->redirect(array('users/'.$model->username));
}
return $this->render('register', [
'model' => $model
]);
}
As you can see I've put there this code
return $this->redirect(array('users/'.$model->username));
Which is supposed to take user to it's own page at domain.com/users/username.
But unfortunatelly url is forming in the following way
domain.com/user/users/username
How can I fix this problem and direct user to domain.com/users/username page ?

Add an extra / in front of the users redirect. it should be
return $this->redirect(array('/users/'.$model->username));
Or you should actually create the url the proper way, that would be the best way to do this, but I do not know the way you have your rules set up so I cannot help you there. I am just guessing here but it should be:
return $this->redirect(array('users/view, 'username' => $model->username));
In this way you are using your url manager, not just hardcoding the url. In the future if you decide to change the link it will be much easier (replace just the url line in your config) and not go in files to change it.

Related

Show a popup on redirect from old to new domain

I need to show a popup when the old domain is redirected to new domain in the nuxt js.
I have modified the . htaccess file and have a modal in the index.vue.
mounted() {
const modal = document.getElementById('modal')
if (document.referrer.indexOf('https://olddomain.com') > -1) {
alert('Previous domain redirected')
modal.style.display = 'block'
}
}
But there is no popup displayed. Is there a better way to do this using nuxt.
You can try the following:
Create a middleware in middleware/popupCheck.js name is up to you..
when you are creating middleware in Nuxt you should export default function, like this:
export default function(context) {
if (context.req.headers['your-custom-header']) {
// Use vuex store to dispatch an action to show a popup or set a cookie
// to listen to. Here the logic should be defined by the implementation.
}
}
The point here is to listen for a header in the request, could be a cookie also, that you have to send from your old site for every request, so make sure it's not something generic, but instead something that you cannot hit easily by mistake..
After you create your middleware you can use it on pages or layouts views, and you should add it in the default object you export:
export default {
middleware: 'popupCheck',
}
Without importing the middleware you just call it by name, this could also be an array if you wish to add multiple middlewares, and the order in that array is important.
There might be a better way to solve this, but this is the first one that came to my mind..

How to Disallow User Access to CRUD Backend

I've got Backpack for Laravel installed and have been using it for some time as an admin back end on a project. I'm also using the spatie/permission module (might come with Backpack, can't remember) to create users for the front end.
Currently, all users are able to access both front end and back end regardless of the group they belong to. I'd like to change that so that only members in an "admin" group are able to access the back end. I've followed the instructions here for separating front end and back end sessions but that's not really what I want as all users are still able to access both sites of the project.
I'm guessing I need to add a guard to the CRUD routes but I'm finding it to be much harder than it should be. Any pointers on how to do this would be greatly appreciated. TIA.
You can create a new middleware and use it in your routes group for admin routes.
To create a new middleware use the php artisan command like so: (you can name the new middleware what ever you want:
php artisan make:middleware RequireAdminRole
Now, inside your new middleware, on the handle function you can have something like this that returns a 403 Forbidden error message:
public function handle($request, Closure $next)
{
$user = auth()->user();
if (!$user) return $next($request);
if (!$user->hasRole('Admin'))
{
// if your sessions are decoupled from the frontend
// you can even logout the user like so:
// auth()->logout();
abort(403, 'Access denied');
}
return $next($request);
}
Here we are using the hasRole method, but there are more that you can use. See the spatie/laravel-permissions documentation for more info.
Now, let's assign this middleware a 'name' so we can use it in our route groups for the admin. Inside the App\Kernel.php file, in the end, inside the $routeMiddleware array add it and give it a new, for example:
'isadmin' => \App\Http\Middleware\RequireAdminRole::class,
And finally, you can add this middleware to your admin routes group (which should be in custom.php file if you're using latest backpack 3.4 version) :
Route::group([
'prefix' => 'admin',
'middleware' => ['web', 'isadmin', config('backpack.base.middleware_key', 'admin')],
'namespace' => 'App\Http\Controllers\Admin',
], function () {
// your routes are here
});
Now all your requests to the admin routes should be protected by the user role check.
Please let us know how it went for you, and if you encountered any issues.
Best regards,
~Cristian

Silverstripe Login params

Im trying to style my login page. My login url is website/Security/login. Im trying to locate the 'login' piece of the url. What have i done wrong below?
public function DisplayPageType() {
$param = $this->request->param('Action');
if ($param === 'login')
{
return 'Login';
}
Thanks
I think that won't work since the controller during render is the Page_Controller and not the Security controller. So the $Action param is not equal to login. It could be index, I'm not sure.
If you just want to check if you're in the login page, you can add this to your Page_Controller:
public function getIsLoginPage()
{
return $_REQUEST['url'] == '/Security/login';
}
Then in your template:
<body class="<%if $IsLoginPage %>login-page<% end_if %>">
A bit dirty but it's the quickest way I know.
Another way is to leverage SilverStripe's legacy support. You can add a css file called tabs.css at mysite/css/tabs.css. If this file exists, SilverStripe will include this in the page.
You can also create templates that SilverStripe will automatically use if they exist:
themes/<theme_name>/Security.ss - If you want your login page to use an entirely different layout.
themes/<theme_name>/Layout/Security_login.ss - If you want to change just the content part (the $Layout section)
I hope this helps.
#gpbnz is right, the $Action param is not equal to login, it actually returns null as accessing $this->request from the Page_Controller when accessing the Security/login returns a NullHTTPRequest.
To get the action, you will want to get the current controller using Controller::curr(). It is then as simple as calling getAction on this controller.
To confirm that the action isn't from a random controller that happens to have an action called login, you can check the instanceof the controller like so: Controller::curr() instanceof Security
This check will still allow it to work for any controller that extends Security though which may/may not happen depending on the project.
I would stick away from actually reading the URL for the information manually though as that can create issues with maintainability in the future.
To bring this to a nice little function:
public function isLoginPage()
{
$controller = Controller::curr();
return $controller instanceof Security && $controller->getAction() == 'login';
}
Otherwise #gpbnz had a good suggestion of using the template system to your advantage for overriding not only the styles but the HTML around it.

Symfony2: Redirect to requested path

I want to redirect the user back to the path from which he started the request.
Example:
/profile
/profile/edit
/profile
OR:
/products
/profile/edit
/products
What do I have to set for this redirection mode?
Inside your controller for /profile/edit you can capture the page they came from with $request->headers->get('referer').
If /profile/edit is a page with a single form, I'd probably just add a hidden field that says where the redirect should go.
public function editAction(Request $request)
{
// If you have a POST value coming from the user, it will be used, otherwise
// assume this is the first time they landed on the page and grab the current
// referer. With this method it doesn't matter how many times they submit the form
// you won't accidentally overwrite the referer URL with /profile/edit. That could
// lead to a confusing loop.
$referer = $request->request->get('referer', $request->headers->get('referer'));
if ($formIsSaved)
{
return new RedirectResponse($referer)
}
return array(
// Your template should include a hidden field in the form that returns this.
'referer' => $referer,
);
}
You could pass a redirect path as a GET parameter — say, redirectTo — to the edit page and after the edit process is complete, redirect to that path.
return new RedirectResponse($request->query->get('redirectTo');
You could make it more robust by checking whether or not that parameter is provided, and if it isn't, redirect to some sort of a default path.

Zend Framework website.com/username

One of the application I am developing using Zend Framework requires the user's profile page to be accessed via website.com/username, while other pages should be accessed by website.com/controller_name/action_name
I am not too sure how can this be achieved, however, I feel this can be done with some tweaks in the .htaccess file.
Can someone here please help me out?
Many thanks in advance
As suggested before, you can use a custom route that will route single level requests. However, this will also override the default route. If you're using modules, this will no longer work example.com/<module>.
I have done this before but only for static pages. I wanted this:
example.com/about
instead of this:
example.com/<some-id>/about
while maintaining the default route so this still works
example.com/<module>
example.com/<controller>
The way I did this was using a plugin to test if my request could be dispatched. If the request could not be dispatched using the default route, then I would change the request to the proper module to load my page. Here is a sample plugin:
class My_Controller_Plugin_UsernameRoute extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
if (!$dispatcher->isDispatchable($request)) {
$username = $request->getControllerName();
$request->setModuleName('users');
$request->setControllerName('dashboard');
$request->setActionName('index');
$request->setParam('username', $username);
/** Prevents infinite loop if you make a mistake in the new request **/
if ($dispatcher->isDispatchable($request)) {
$request->setDispatched(false);
}
}
}
}
What about using Zend_Controller_Router_Route, look here the link http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.standard.variable-requirements