Form::setData([]) to remove input values of a contact form after sending email not working in CakePHP? - cakephp

I've created a contact form in Cakephp 4 refering to the doc (https://book.cakephp.org/4/en/core-libraries/form.html).
I have a problem to remove input values after the email has been sent.
Here's my ContactController.php :
<?php
namespace App\Controller;
use App\Controller\AppController;
use App\Form\ContactForm;
class ContactController extends AppController
{
public function index()
{
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
$this->Flash->success('We will get back to you soon.');
$contact->setData([]); // I want to remove data in contact form after the email has been sent, but it doesn't work
} else {
$this->Flash->error('There was a problem submitting your form.');
}
}
$this->set('contact', $contact);
}
}
Why is $contact->setData([]); in the code abode not removing data in my contact form ?

The form helper will prefer request data, eg the POST data from your form submit, otherwise the input would always get lost when a validation error occurs.
If you want to show the form page again after successful submit, then you should redirect to the current page, that's called the PRG (Post-Redirect-Get) pattern.
So instead of $contact->setData([]);, do:
return $this->redirect(['action' => 'index']);
That's also what your baked controllers will do for add and edit actions.
See also
Cookbook > Controllers > Redirecting to Other Pages

Related

how to add custom validation message in suitecrm api

I configure json api in my suitecrm and now i want to add validation mandatory fields for some parameter please suggest me how to add validation and custom message.
I tried to add validation but can't get success is any idea how to configure validation message display
Use before_save logic hooks in that module in which you want to add validation then create you own method to check validation e.g. for checking pan number you can use pan regix then apiException
Hello try this one to your custom api controller
here`s my sample custom/application/Api/V8/Controller/CustomController.php
namespace Api\V8\Controller;
use Slim\Http\Request;
use Slim\Http\Response;
class CustomController extends BaseController
{
public function saveLeads(Request
$request, Response $response, array $args)
{
try {
$jsonResponse = $request->getParams();
$leadBean = \BeanFactory::newBean('Leads');
if(empty(jsonResponse['name'])
{
$resultMessage['Error'] = 'Please filled up the Name';
}else{
$leadBean->name = jsonResponse['name'];
$leadBean->save();
$resultMessage['Succes'] = Leads Has been created';
}
return $this->generateResponse($response, $resultMessage, 201);
} catch (\Exception $exception){
return $this->generateErrorResponse($response, $exception, 400);
}
}

Laravel: resetting password without getting redirect response

I am building an angular application and want to implement password reset. However, default laravel config doesn't appear to allow one to do this using purely XMLHttpRequest ($http.post) requests and responds with a 302 redirect.
I managed to get postLogin and postRegister to work without issuing redirects by implementing said methods in authController class and returning a json response, doing this overrides the default laravel implementation of said methods. No such luck with postEmail and it appears the method is not hit at all, I just get a 302 response back immediately.
Ideally, other than to check their E-mail, I don't want the user to leave the single page angular application at all.
So 1. User posts E-mail to postEmail -> Email with reset link or better 'reset code' is sent to E-mail address -> User then inputs the reset token code into the already open web app or if it can't be done, browse to reset password page opened in new tab.
I tried implementing postEmail method as such:
public function postEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$response = Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject($this->getEmailSubject());
});
switch ($response) {
case Password::RESET_LINK_SENT:
return response()->json(['msg' => 'A reset link has been sent to your E-mail'], 200);
case Password::INVALID_USER:
return response()->json(['msg' => 'This E-mail cannot be found in our system'], 200);
}
}
Also, where is template for the E-mail with the reset link that laravel sends out ?
You can create a PasswordController within the App\Http\Controllers\Auth namespace to extend the password reset methods.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\PasswordBroker;
use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller
{
use ResetsPasswords;
public function postEmail(Request $request)
{
}
}
To overwrite the email templates you can create a reminder.blade.php in the app/views/emails/auth directory, or change the location of the template file in the app/config/auth.php config.
while the accepted answer is completely valid, another solution without overriding the original notification class is as follows, ResetPassword provides a static method called createUrlUsing which accepts a Closure, So we can override the URL as something like the below:
use Illuminate\Support\Facades\Password;
use Illuminate\Auth\Notifications\ResetPassword;
...
$status = Password::sendResetLink(
['email' => $args['email']],
function ($user, $token) {
ResetPassword::createUrlUsing(function ($notifiable, $token) {
// This is where you override the URL, you can also take a look at
// the `url`, `action` and `route` functions in Laravel and skip
// `sprintf` if you prefer to stick to Laravel functions only.
return sprintf(
"%s/%s/?token=%s&email=%s",
config('your.optional.frontend_url'),
config('your.optional.password_reset'),
$token,
$notifiable->getEmailForPasswordReset(),
); // frontend_url/password_url/?token=TOKEN&email=EMAIL
});
return $user->notify(new ResetPassword($token));
}
);
// This is an optional way to handle the final response, you can convert it to
// JSON or ignore it.
return $status === Password::RESET_LINK_SENT
? ['status' => __($status)]
: throw new Error(__($status));
This piece of code should be placed at a new route to handle password reset requests instead of using the default Laravel one.

CakePHP form input filed empty after get submit

echo $this->Form->create('Driver', array('type' => 'get'));
echo $this->Form->input('name');
echo $this->Form->end('Search');
as result $this->request:
query => array(
'name' => 'some name'
)
Problem is input form is empty after search although $this->request->query['name'] = 'some name'
Everything works as expected when change form back to post
Edit. Included the model and the controller. For testing I use clean install.
Model (Driver.php):
App::uses('AppModel', 'Model');
class Driver extends AppModel {
public $displayField = 'name';
}
Controller (DriversController.php):
App::uses('AppController', 'Controller');
class DriversController extends AppController {
public function index() {
$drivers = $this->Driver->find('all');
$this->set(compact('drivers'));
}
}
In your controller code you do not show us where you are trying to access the submitted form values so I will try and give some general information to get you moving.
To access your form data, you need to cool use request. To see exactly what is going on, enter in your controller one of the below...
print_r($this->request->data);
or
print_r($this->request);
Either of those will show you any data registered with CakePHP.
If you want to save this save using your Models. use...
$this->Driver->save($this->request->data)
You might want to check it is a post first though.. lets complete the code...
public function submit() {
if ($this->request->is('post')) {
$this->Driver->create();
if ($this->Driver->save($this->request->data)) {
$this->Session->setFlash('Saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('FAILED');
}
}
}
The information above can be read in further detail here.
You can set form values by assigning to $this->data.
$this->data = $this->request->query;

Extending cakephp auth component with extra conditions

Problem: I want to show different error messages to user based on user status on login (using ajax). For ex: If the user status is pending, I want to show one message, or else if the user status is disabled, I want to show another message. Only active user should be able to login.
After some searching found that I can use
identify method
or
I should use write my conditions inside "if
($this->Auth->login())" condition in my login method.
If I use 1st method in custom component (which will extend auth), hope it can only return true or false, right ? Can it set error messages and return, so that I can get it from my controller ?
If I use 2nd method after allowing the user to login I should check the status and if it is not active, I should remove the login credentials from Auth/Session. how can I do that ? Is this a good method ?
Any other better solution ? Im using cakephp2.0
I would create a class extending from BaseAuthenticate for your users and set this up within your AppController.
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => ..... ,
'logoutRedirect' => ..... ,
'loginAction' => ..... ,
'authenticate' => array('YourUsers'),
)
);
And then create the class
<?php
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
class YourUsersAuthenticate extends BaseAuthenticate {
public function authenticate(CakeRequest $request, CakeResponse $response) {
// your code goes in here
}
}
You can return false from within the authenticate to deny the user access or can return an object on success that will get stored in $this->Auth->user which you can interogate later.
If you get stuck, the CookBook has a lot of detail about this.

cakephp: signup link on register page not working

I'm trying to use the Auth component only for viewing the progress report of a student. For all other links, authentication is not required. For the discussion board i already have a separate forum plugin.
When the user clicks the progress report link on the navigation bar, the user is directed to /merry_parents/register. Here, new users will click on signup link and existing users will click on login link.
However, my signup link is not working. I'm not being directed to the signup page when I click on signup. What am I doing wrong? any help is much appreciated.
The following is my code:
register.ctp
<?php
echo $this->Html->link('Sign Up','/merry_parents/signup').' for new user |'.$this->Html->link('Login','/merry_parents/login',array()).' for existing user';
?>
merry_parents_controller.php
<?php
class MerryParentsController extends AppController{
var $name='MerryParents';
var $components=array('Auth','Session');
function beforeFilter(){
//$this->Auth->authorize='actions';
$this->Auth->loginAction=array('controller'=>'merry_parents','action'=>'register');
//$this->Auth->loginRedirect=array('controller'=>'merry_parents','action'=>'report_card');
}
function register(){
}
function login(){
}
function logout(){
}
function signup(){
if (!empty($this->data)){
//$this->Auth->password($this->data['MerryParent']['password2'] used to get what the hashed password2 would look like.
if ($this->data['MerryParent']['password']==$this->Auth->password($this->data['MerryParent']['password2'])){
$merryparent_id=$this->MerryParent->field('id',
array('MerryParent.name'=>$this->data['MerryParent']['name'],
'MerryParent.email'=>$this->data['MerryParent']['email'])
);
echo $merryparent_id;
print_r($this->data);
if ($this->MerryParent->save($this->data))//record with $merryparent_id is updated
{
$this->Session->setFlash('You will be receiving an email shortly confirming your login and password.');
$this->Auth->login($this->data); //automatically logs a user in after registration
$this->redirect(array('controller'=>'pages','action'=>'home'));
}
else
echo $this->Session->setFlash(__('Your admission could not be saved, please try again!',true));
}//end if ($this->data['MerryParent']['password']....
else
echo $this->Session->setFlash('Typed passwords did not match');
}//end if (!empty($this->data))
}
}
?>
You have to use following code in your MerryParentsController controller.
function beforeFilter() {
$this->Auth->allow('signup');
}
This will allow your register method to get register.
For more information please read http://book.cakephp.org/view/1255/AuthComponent-Methods

Resources