Setting returnURL for CButtonColumn button - yii

I'm looking at the controller for the default Delete button in the CButtonColumn class. It manages to return to the previous web-page after deleting a CGridView line and remain on the same page of the CGridView, as opposed to going to the first page. The lines responsible for this in the associated controller seem to be:
if (!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
I would like to create a new custom button that has this behavior (i.e. returning to the previous view without resetting the pagination to page 1), but simply including the above lines of code in the button's associated action does not do the trick. I think I need to send that 'returnUrl' parameter somehow, but I cannot figure out how :)

The 'returnUrl' code you are looking at uses a POST variable for the returnUrl. To use this, you will need to POST that somehow. On the View this code is called from I am assuming there is a <input name="returnUrl"> field in the form. You should make sure this field (populated with the correct URL value) is on all of the Views you are POSTing from in order to access that POST variable in your Controller action.
If you are POSTing to the deleteAction via AJAX, I think you can set the $_POST['returnUrl'] variable with the jQuery AJAX function.
Another way to go might be to use CWebUser's returnUrl SESSION variable instead of this POST variable. I have never done this, but it's built in to Yii so I assume it works OK.
I never really liked the hacky $_POST['returnUrl'] that Gii generates anyway.
ANOTHER thing you could do, possibly, is look at the $_SERVER['HTTP_REFERER'] variable, and use that for the return redirect in your deleteAction. I don't know if that will be set correctly though, with complications from the 302 redirect/rewrites that Yii does.
Good luck!

You can set the return url via the CHtml::link call. Here is an example using delete
CHtml::link(
'Delete',
'#',
array('submit'=>array('delete','id'=>$model->id),
'params'=>('returnUrl'=>'controller/action...'),
'confirm' => 'Are you sure?'
)
);
Pulled from this Stackoverflow answer.

Related

overriding basePAth for Edit or ShowButton

In reference to this: https://github.com/marmelab/react-admin/pull/1491
That is not overriding the url that gets called.
I thought this meant to change the basePath of the URL that hoes to the API not the internal one to the frontend site, hopefully that makes sense.
So essentially I want to override the basePath so I can call a different URL on the backend side. If this is not what was intended , how can I override a action of the EditButton or ShowButton to call a different URL?
Or the other option that I can think of is: if we have a way to override the attribute that gets picked at the moment the button gets clicked, that is for an instance for complex structures instead of sending the id to lookup you could use something like: user.id.
Thanks in advance.
I guess the answer to this is to customise the dataProvider. But I don't see it as a clean solution to have to customise the dataProvider for such a case scenario :(

Html.RenderAction uses Post instead of Get

I have a simple form on my page. When submitted, it checks if ModelState.IsValid and returns the View with the same model if it's not valid.
On the same page, I'm rendering an action that contains another form like so:
Html.RenderAction("AccountNote", new { id = Model.ID });
Everything works fine until I submit the form on my page and the validation fails. When it shows the page again, the AccountNote action's Post event fires when I'd expect the Get event to fire. I guess it makes sense why it's happening since it's the post that action that's rendering the view, but I want the Get event to fire instead.
public ActionResult AccountNote(int id)
{
//code goes here...
return PartialView(model);
}
[HttpPost]
public ActionResult AccountNote(AccountNoteViewModel model)
{
//code goes here...
return PartialView(model);
}
Am I doing something incorrect? Or is there some trickery I have to do to make this work? I would expect the Html.RenderAction to always assume GET instead of POST.
One solution would be to have only one AccountNote() action method. Then it will be called regardless of GET or POST. You might have to modify your logic a bit if you were using POST version of AccountNote().
And you can decorate it with [ChildActionOnly] attribute.
Since I know, there is not any solution for this problem out of the box. RenderAction and Action methods, consider the current request for deciding on to use which verb.
But you can rename them. For example rename the one that is restricted to HttpPost to AddAccountNote and leave the other one with the current name and without specifying its verb.
Would RenderPartial be an option for you?
More discussion on this topic can be found here: RenderAction calls wrong action method

Yii captcha never passes the validation even if, right letters are in place

This is on my model rules:
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),
This is on my _form:
$this->widget('CCaptcha', array('buttonOptions' => array('class' => 'captcha-anchor')));
On my accessRules:
array('allow','actions'=>array('create','index','view','member', 'captcha'),
'users'=>array('*'),
),
I keep getting,
"The verification code is incorrect"
no matter what I do.
I'm using AjaxValidation with CActiveForm, and wish to keep using it.
Any clue how to fix this?
Please don't post any link, if you happen to know the answer, please describe it, so we can discuss if in need.
Please note that the captcha image is displaying and reloading. No issues there.
Thanks.
I have same problem and it return false every time because :
1- I define Get POST in some base controller and i send a ajax request to home controller which extended from base , because i can not call base controller directly so i change ajax request to current controller not home controller for all pages.
2- I hard coded JQuery in my layout so Yii load two JQuery in the Page so it send 2 request , first verified and second fails, i disabled JQuery auto load helping by this link.

Yii CAPTCHA url is broken

I want to create an AJAX-registration form on my Yii-project. So on every page I have a login-button, which shows a popup if the user isn't authorized. In that popup he can see registration form with email field, password field, and CAPTCHA (default Yii captcha).
So, my model for user's registration is User. There is a validation rule:
array('code', 'captcha', 'allowEmpty'=>!Yii::app()->user->isGuest),
My controller, where all user's actions are, is User (url: site.url/user/) and I added there captcha action:
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
'foreColor'=>0x000000,
),
In my next code:
$this->widget('CCaptcha', array(
'clickableImage' => true,
'showRefreshButton' => false,
))
And here is a problem:( Being inside a popup, which can be shown on every page (index page, for example, which belongs Main controller) captcha wants to load an image from that controller (from /main/captcha, not /user/captcha).
Adding captcha in every controller is bad idea, so I added
'captchaAction' => '/user/captcha',
But after that captcha wants to load from an url
http://site.loc/user/captcha/v/4fe99aca1bbed
User-friendly url's crashed captcha and I can't avoid it (as I think, not being a yii-expert, it's because of common path-config).
Is there an easy solution to solve this? Should I repair URL's or re-configure CAPTCHA?
So, while I was waiting for help, I solved the problem by myself :)
In my project i separated my controllers into the next hierarchy:
/frontend
/backend
All controllers for common users are (of course) in Frontend section, including UserController and MainController.
Yes, I wrote some configs to hide /frontend/ in URL's like this:
'<c:\w+>/<a:\w+>' => 'frontend/<c>/<a>',
And i was sure, that string in my CAPTCHA config ('captchaAction' => '/user/captcha') knows where to go (and it was almost so!), but NO!
I should write FULL PATH to my controller and action like below:
'captchaAction' => '/frontend/main/captcha',
As I said in question, I placed my CAPTCHA action in UserController, but now you can see it is located in MainController (i deleted it from UserController)
And I got an error:
CCaptchaValidator.action "captcha" is invalid. Unable to find such an action in the current controller.
So, to solve this, I just had to use a property captchaAction of CCaptchaValidator in my User MODEL! Code:
array('code', 'captcha', 'captchaAction'=>'/frontend/main/captcha', 'allowEmpty'=>!Yii::app()->user->isGuest)
So, now my AJAX Captcha validation works correctly where I want.
Good luck with Yii's default CAPTCHA, dear community!

A better way of passing variables from controller to view in symfony

Hey.
I've got a login form with post as method. The action goes to 'auth/login' and will check the database if the user exists. If the user exists, I call the $this->getUser->setAuthenticated(true);. After this I want to redirect to a welcome page if success.
If the login failed, I would want to tell the user so in the view of course. But settings variables in the controller only if login failed, and check in the view if each of those variables are set, is a lot of work?
This means I have to check almost all variables I want to use in the view set from the controller. If it should happen that it is not set, and I just go ahead and echo it, I get an error from symfony, and production stage-mode-ish don't show anything but an 500 internal server error .
Thanks
EDIT:
This is my current, new and better solution. Still looking for feeback.
in /templates/loginSuccess
if ($sf_params->has('bad_login')) {
echo "Wrong username or password";
}
And in my controller:
$this->redirect('auth/login?bad_login=');
Take a look at how sfDoctrineGuardPlugin (the de-facto standard for authentication) does it: they created sfGuardValidatorUser and use it as a post validator in the signin form.
Advantage of this method: the form takes care of the username/password validation, you do not need to put that code in your action. It simplifies that to a simple $form->isValid() { $this->redirect("#homepage"); }.
It seems like you could use symfony's form to take care of the validation. Since the forms show errors built in, you could put this into the form validation and then your controller looks something like:
$form = new LoginForm;
if ($request->isMethod('post'))
{
if ($form->isValid())
{
$this->redirect('account');
}
else
{
// this would show the form, and since you put the login in the form validation it will show errors. You could have the username show the error
}
}
To do what you are doing though, I'd recommend this. That way you aren't accessing any parameters in the view as well.
Controller:
$this->bad_login = $this->getParameter('bad_login',false);
View:
if ($bad_login) { echo 'bad login'; }
Use forward()
Put all the logic required for the view population into separate method of a controller, and call it in both places.
Use cgratigny's solution - put login form and processing code in a single action, and redirect to welcome page if isMethod('post') && $login_success