I have a question and I can't find a solution yet, I apologize if I can't be clear on my question, but follow below.
In October, when I am creating a navigation menu, the parent menu forces me to take a route, however, many times the user cannot have permission for a certain page, example below in the image.
Possible solution:
Create a route and put several "ifs" in it to redirect the user, the problem with this is that the work would be extremely repetitive for each plugin ...
My question would be, how could I create a route that would automatically identify what permission the user would have at the moment and redirect to the correct page in a dynamic way for each plugin?
Or was the solution I indicated the only way?
I have one solution in mind.
Just make One extra fake controller and make index action of that controller.
In this index action we can have our own permission check and based on that we can redirect user to our predefined location.
Now for main menu just point URL to => myplugin/fakecontroller/index
this controller has no permission means its public so every one can use it.
Now in index action check permission of current user and based on that you can select redirect url.
// in fakecontroller's index action
$redirectUrl = 'default-url';
if($this->user->hasAccess('bla-bla')) {
$redirectUrl = 'some-other-url';
}
return \Redirect::to($redirectUrl);
To make it more dynamic with multiple plugins
To make it more dynamic you can just pass id of plugin to index action. make sure plugin url will be same for all other plugins. we just change id
Any how you have to use if statements because you want custom behaviour and i don't think we can add those info in to backend and if we try to implement that it will take too long. So, for now I have other solution which can make it little bit easy with multiple plugins.
for ex.
for plugin-A main menu url could be myplugin/fakecontroller/index/plugin-A
for plugin-B main menu url could be myplugin/fakecontroller/index/plugin-B
// fakecontroller
$pluginWiseRedirect = [
'pluginA' => [
'permission-name' => 'redirect-url-A',
'bla-bla' => 'new-url-A'
],
'pluginB' => [
'permission-name' => 'redirect-url-B',
'bla-bla' => 'new-url-B'
],
];
// in fakecontroller's index action
public function index($pluginId = 'pluginA') {
$redirectUrl = 'default-url';
$permissionName = 'permission-name';
if($this->user->hasAccess($permissionName)) {
// please make check here for key exist
$redirectUrl = $this->pluginWiseRedirect[$pluginId][$permissionName];
}
$permissionName = 'bla-bla';
if($this->user->hasAccess($permissionName)) {
// please make check here for key exist
$redirectUrl = $this->pluginWiseRedirect[$pluginId][$permissionName];
}
return \Redirect::to($redirectUrl);
}
if any doubts please comment.
Related
So what i have at the moment is a normal resource route with index, create, store, edit, update, the usual. In the Index I have a few filter options which filter out the entries. Simple enough. What I want to have is that the filter options be saved , and when you create, update or delete that when you are redirected back to the index that your filter options still be saved and filtered. The issue I'm having is that I don't want to be redirecting unnecessarily. The filter is in a form and it keeps posting to the index every time its values changes. In that case I don't want it to be a redirect. So far I've tried sorting out if its a redirect or just a filter that has changed. I want to be able to tell if the previous route is the same as the the current route in this case the index route. However the resource all start with the same route name. The redirect url is stored in the session under the 'cultivar_form_return_url' variable and then put into a variable to be used in checking if a redirect is required.
session(['cultivar_form_return_url' => $request->fullUrl()], '');
$redirect_url = $request->session()->get('cultivar_form_return_url', '');
if($redirect_url && !$has_filtered && !$filter) {
return redirect($redirect_url);
}
$cultivars = $query
->orderBy('name')
->paginate(20);
return view('database.cultivars.index',compact('cultivars','filter','redirect_url'));
The $redirect_url is the url created when the filter request was submitted. I use this url to redirect to when I'm returning from a create, update or delete.
Which contains the parameters for the search. I check if the redirect_url exist, for the second parameter of the redirect i have created a variable that starts of as false, and if my request has parameters for the filter within each function i set the variable to true as follows.
if($request->has('input')) {
$has_filtered = true;
$query = $query->where('input', $request->input);
$filter['input'] = $request->input;
}
The last parameter for the redirect check is the filter variable which contains my filter options which starts out as empty and gets set at each function if that particular filter is set.
$has_filtered = false;
$query = (new Cultivar);
$filter = [
'search' => null,
'crop' => null,
'is_rootstock' => null,
'is_public' => null,
];
I would like to differentiate between redirects and the filter options merely being changed. Thank You. Any help is appreciated.
After thinking more about the problem I think I might have an answer to my question.
$redirect_url = $request->session()->get('cultivar_form_return_url', '');
if($redirect_url && !$has_filtered && url()->previous() != route('database.cultivars.index')) {
session(['cultivar_form_return_url' => '']);
return redirect($redirect_url);
}
session(['cultivar_form_return_url' => $request->fullUrl()]);
This stops it from redirecting to itself over and over while still keeping the filter options in. While also not redirecting unnecessarily.
So my previous answer, after a bit of testing still has a few bugs. So I have come up with a better solution. Instead of saving the redirect url to the session I put it into the form.php as one of the inputs. Both the edit and create works through the form.php. I just hid the field and use that field to keep track of the previous state which the filter was.
<input type="hidden" name="redirect_url" value="{{ $redirect_url }}">
The redirect route starts off as the generic route('database.cultivars.index') then I check if their is an old state in order to pass on the redirected route if there was a validation error or anything that might redirect you to the same page in order to keep the filter settings. Then I then I check if the previous route matches the current route and if it does that means the page was refreshed or there was a validation error. If The previous and current routes are not the same that means you just came from the index either for editing or creating. Then I grab that route and send it to the view to be put into the hidden field and the process gets repeated.
$redirect_url = route('database.cultivars.index');
if($request->old('redirect_url')) {
$redirect_url = $request->old('redirect_url');
} else if(url()->previous() != route('database.cultivars.edit', $cultivar)) {
$redirect_url = url()->previous();
}
When you have successfully created or updated a cultivar you are then redirected to the redirect Url if there is one. If there isn't one you are just redirected to route('database.cultivars.index'). This part is both in the store and update controller functions.
if($request->has('redirect_url')) {
$redirect_url = $request->redirect_url;
}
if($redirect_url && starts_with($redirect_url, route('database.cultivars.index'))) {
return redirect($redirect_url);
}
With this answer there are no bugs and no unnecessary redirects.
I am designing a website, that has my groups and other groups that are present on two different webpages. Both my groups and other groups have an option to see the members of each group which is redirecting to a members.phtml page.
Now I want to add a back button on members.phtml page at the top that will go to the previous page (my groups/other groups). Is there a way to save the current url and send it to members.phtml page?
You could use the redirect plugin and add a query param previous to the url. Check this answer for an example and check the ZF2 documentation here on the redirect plugin. It would become something like this:
http://www.example.com/members.phtml?previous=my_groups
In the controller for your my_groups route where you added the redirect url to your members page you will need to add the query param to the redirect route:
$previous = 'my_groups';
$this->redirect()->toRoute(
'members',
array(
'action' => 'index'
),
array( 'query' => array(
'previous' => $previous
))
);
Now when the members.phtml page is requested you can find the previous page inside the query parameters of the request object. You can easily access it in your controller like this:
$previous = $this->params()->fromQuery('previous'); // my_groups
Now you know whether the members page was accessed from my_groups or other_groups and you can render the back button accordingly.
UPDATE
Some extra information after your comment...
You can find current page url for example by using:
$this->getRequest()->getRequestUri();
Or you can get the current matched route:
$this->getMvcEvent()->getRouteMatch()->getMatchedRouteName();
And you can use this to dynamically add the previous url.
I want to create a search form.
When I enter my query and press the submit button, I want submit to a URL - domain.com/query/there_is_my_query, but how to make this?
If I change method to GET, that URL will be domain.com/query/?query=there_is_my_query.
But if I change action to /query/, then In controller put $_POST['search'], that URL will be domain.com/query.
Edit!
I thought and decided to leave the following url - domain.com/query/?search=there_is_my_query.
To let you know, search engines do not use search forms.
So there is no point in making them search engine friendly.
You can either modify your index.php to redirect any request containing $_GET['query'] via redirect like this:
header('Location: http://domain.com/query/' . urlencode($_GET['query']));
Or otherwise you need to use JavaScript to create the new URL once the user clicks the submit button. Neither solution seems overly reasonable, if you ask me.
The following will work, however it is considered bad practice to use global arrays in Kohana:
Route::set('query', function ($uri)
{
$query_string = $_SERVER['QUERY_STRING'];
if (preg_match('/query=(.+)/', $query_string, $matches))
{
return array(
'controller' => 'index',
'action' => 'query',
'id' => $matches[1],
);
}
}, '(<action>(/<id>))');
The problem is that Kohana's routing system is not designed to work with the query string. If you really need to go this this way, then you'll have to move the logic out of Kohana into the .htaccess file, using mod_rewrite.
You can use the Apache rewrite module for redirect the requests to a point (bootstrap). This bootstrap will parse the URLs and it will get the params.
In Zend Framework I have an Action Helper that loads a login form on most pages. This happens in the preDispatch() method of the Helper and I want to setAction() on the form so that it posts back to the current URL.
What's the best way to access the current URL / route from within the Action Helper? Access the Request (via the Action Controller), then pull then getActionName() and getControllerName(), and concatenate them with baseURL()?
Is there a simpler way? (Set action requires the URI string as a parameter).
Thanks!
You can do as #Elie suggested. However, if you want to use ZF methods for this, you can have a look at this:
$request = Zend_Controller_Front::getInstance()->getRequest();
echo $request->getHeader('referer'); // referer's address
echo $request->getRequestUri(); // current address
I found that I didn't need to access the current URL / route from within the Action Helper. By leaving the form action blank, it automatically posts to the current URL. Perfect.
If I understand correctly, when the user logs in, you want to send them back to the page where they came from. The code I use to do this is:
// the user has come from a particular page - send them back
if($_SERVER['HTTP_REFERER']) {
$this->_redirect($_SERVER['HTTP_REFERER']);
} else {
// the user has come from the home page, or this page
$this->_redirect('/');
}
which is located in the login action (i.e. LoginController->loginAction()).
I have used Yii::app()->user->returnUrl but it always redirect me to localhost/index.php. Is there any particular configuration or some pieces of code that other programs that I must write? If you have another solutions let me know it.
#aslingga, can you please explain what you're trying to do with returnUrl? Are you just trying to get back to where you were after logging in, or are you using it somewhere else?
This is from the Yii documentation:
Redirects the user browser to the
login page. Before the redirection,
the current URL (if it's not an AJAX
url) will be kept in returnUrl so that
the user browser may be redirected
back to the current page after
successful login. Make sure you set
loginUrl so that the user browser can
be redirected to the specified login
URL after calling this method. After
calling this method, the current
request processing will be terminated.
In other words, if the page you're trying to request requires authentication, the URI of the page you're on gets stored in a session variable. Then, once you've logged in, it takes you back to that page.
One way I'd recommend troubleshooting is to do a print_r($_SESSION); just to make sure the returnUrl is actually being stored. Then you'll be able to check if index.php is being stored as returnUrl or if you're just being redirected there for some reason.
Looking at the CWebUser methods getState and setState might also be helpful.
I know this question is old but maybe this will help someone out since I didn't couldn't find a decent answer anywhere.
How getReturnUrl works
Setting a default return URL for your Yii app requires a bit of customization. The way it works out of the box is that you specify the default return URL each time you call it:
Yii::app()->user->getReturnUrl('site/internal');
The idea being that if a user were to visit a page that requires authentication, they will get redirected to the login page, but not before the site running
Yii::app()->user->setReturnUrl('site/visitedpage');
Now when the user logs in, they will be returned to the page they intended to go to.
While I like that functionality, having to set the default return URL each time is dumb. If you want to change the default return URL, you have to go find it throughout your code. I suppose you could set the value in a site parameter and call
Yii::app()->user->getReturnUrl(Yii::app()->params['defaultReturnUrl']);
I don't think I have to explain why that solution is annoying too.
My Solution
So when getReturnUrl is called without any parameters, it returns either '/index.php' or just '/'. This is fine in some cases, but not always. This is better IMO.
First, extend the CWebUser class and add the following extras
class WebUser extends CWebUser {
// default return URL property
public defaultReturnUrl;
// override the getReturnUrl method
public function getReturnUrl($defaultUrl=NULL) {
if ($defaultUrl === NULL) {
$defaultReturnUrl = $this->defaultReturnUrl;
}
else {
$defaultReturnUrl = CHtml::normalizeUrl($defaultUrl);
}
return $this->getState('__returnUrl',$defaultReturnUrl);
}
}
Now, let's add a couple items to the user component array.
'user' => array(
'class' => 'WebUser',
'defaultReturnUrl' => 'site/internal'
)
Not only does this allow you to set a default return URL in the config, but also maintains the ability to set a different default return URL and use the setReturnUrl functionality.
I think, you must set it:
Yii::app()->user->setReturnUrl('controller/action');