Sending string/text to a method/function in cakePHP - cakephp

Good Day to all. I am currently developing a chat application using cakePHP. It will be a chat application that focuses on answering questions. That means the user will receive an automated response based on his/her question. I am working on the chat interface right now that doesn't require the user to login. The chat application will only be interacting to a database table once the user has sent the question. Now my problem is on how to send the question to a method in the controller where it will be parsed. I tried to do the following in the view file:
<!--View/People/index.ctp-->
<h1>This is the chat interface</h1>
<?php $this->Html->charset(); ?>
<p>
<!--This is the text area where the response will be shown-->
<?php
echo $this->Form->create(null);
echo $this->Form->textarea('responseArea', array('readonly' => true, 'placeholder' =>
'***********************************************************************************
WELCOME! I am SANTI. I will be the one to answer your questions regarding the enrollment process
and other information related to it. ***********************************************************************************', 'class' => 'appRespArea'));
echo $this->Form->end();
?>
</p>
<p>
<!--This is the text area where the user will type his/her question-->
<?php
echo $this->Form->create(null, array('type' => 'get', 'controller' => 'people', 'action' => 'send', ));
echo $this->Form->textarea('userArea', array('placeholder' => 'Please type your question here', 'class' => 'userTextArea'));
echo $this->Form->end('Send');
?>
</p>
This is the controller:
<!--Controller/PeopleController.php-->
<?php
class PeopleController extends AppController{
public $helpers = array('Form');
public function index(){
}
public function send(){
//parsing logic goes here
}
}
?>
As you can see, I am telling the form in index.ctp to point the action to the send() method in PeopleController so it can parse the question before interacting with the database. The problem that arises when I click the button is that I am always redirected to /users/login which is not what I want to happen. I just want the application to point itself to /people/send. What seems to be the problem in that case? I have tried to look for answers both in the Internet and in the documentation and then tested them but nothing has resolved the problem so far. Can anyone please help me on this? I've been trying to resolve this for so many days.
I keep on getting this error:
Missing Method in UsersController
Error: The action *login* is not defined in controller *UsersController*
Error: Create *UsersController::login()* in file: app\Controller\UsersController.php.
<?php
class UsersController extends AppController {
public function login() {
}
}

If you are using Auth Component, then you might need to change your PeopleController code:
<!--Controller/PeopleController.php-->
<?php
class PeopleController extends AppController{
public $helpers = array('Form');
public beforeFilter()
{
parent:: beforeFilter();
$this->Auth->allow('index', 'send');
}
public function index(){
}
public function send(){
//parsing logic goes here
}
}
?>
This is because of you used people/send as a form action. And the user is not logged in, it means there is no any Auth session has been set. Thats why it always redirect the user to login page, and if there is not login page, then it will show you the error.
So I made the send() method also public, so that anyone can access it.
Hope this concept will help you.

Related

Submit form to another application

So I started to play around with cakePHP after i did the blog tutorial (yes im new), and i would like to do something complicated. Like, theres a comment form, which is simple it contains Name and the Comment. And I would like to send the data to another application in the same host, which is save this comment in the DB. Currently the Comments/add.ctp saves it.
Thanks for any advice!
So theres the CommentsControll.php
<?php
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
if($this->Comment->save($this->request->data)){
$this->Session->setFlash('Your comment is saved!')
}
}
}
}
?>
And theres the Comments/add.ctp file
<?php
echo $this->Form->create('Comment');
echo $this->Form->input('name', array(
'label' => 'Your Name'
));
echo $this->Form->input('commenttext',array(
'label' => 'Your Comment'
));
echo $this->Form->end('Submit');
?>
Solution HttpSocket
CakePHP includes an HttpSocket class which can be used easily for making requests. It is a great way to communicate with external webservices, or remote apis.
// in your controller
App::uses('HttpSocket', 'Network/Http'); // This should be at the top of your Controller
class CommentsController extends AppController{
public $components = 'Session'
public function add(){
if($this->request->is('POST')){
$this->Comment->create();
$HttpSocket = new HttpSocket();
$response = $HttpSocket->post('http://example.com/add', $this->request->data));
// Get the status code for the response.
$code = $results->code;
if($code == 200) {
$this->Session->setFlash('Your comment is saved!');
} else {
$this->Session->setFlash('Opps! Somthing is wrong!');
}
}
}
}
Also see here CakePHP HttpSocket

Passing data via POST from an element to controller/model Cakephp

I am pretty new to cakephp, I have an uploader form and would like to pass all of the data using POST to the controller and model so that it will save to the database. So far there are no cakephp errors occuring but no data is being passed.
Controller Code:
<?php class Controller extends AppController {
public function add() {
if ($this->request->is('post')) {
$this->File->create();
if ($this->File->save($this->request->data)) {
$this->Session->setFlash(__('Your file has been liberated :)'));
$this->redirect($this->referer());
} else {
$this->Session->setFlash(__('Something went wrong!'));
}
}
}
}?>
View Code:
<?php echo $this->Form->create('File'); ?>
<input type="uploader" name="selected-file" style="visibility: hidden;"/>
<?php echo $this->Form->end('Finish'); ?>
Model Code:
<?php class File extends AppModel {}
?>
Please, check input specification you can see there, that there are no "uploader" value for type attribute. Maybe you mean type="file".
Also, if you want to upload files, please, use
echo $this->Form->create('File', array('type' => 'file'));
this will produce correct enctype attribute enctype="multipart/form-data". such enctype needed if you send files by POST.
Also, you use style: style="visibility: hidden;" which should hide file input field, so, maybe you use some flash uploader or ajax, but this is not demonstrated in your code. If you provide more code, we can provide more concrete help to you.
and counter question: how you debug your code?

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;

cakePHP auth component not working

I have an issue with cake's auth that I simply can't seem to get past (i've been debugging and trying different tutorials for the last two days). As far as I can see it should be very simple, the problem is whenever i try to login, it just refreshes the login page. I cannot for the life of me figure out why! My only conclusion is that there must be something (basic) which tutorials take for granted that I have missed.
Here are a couple of snippets:
users_controller.php
class UsersController extends AppController {
var $name = 'Users';
function beforeFiler() {
parent::beforeFilter();
}
function login() {
}
function logout() {
$this->Session->setFlash('You have successfully logged out.');
$this->redirect($this->Auth->logout());
}
}
app_controller.php
class AppController extends Controller {
var $helpers = array('Html','Form','Javascript');
var $components = array('Auth');
function beforeFilter() {
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'contents', 'action' => 'index');
$this->Auth->logoutRedirect = array('controller' => 'contents', 'action' => 'view');
$this->Auth->loginError = 'Something went wrong';
$this->Auth->allow('register', 'view');
$this->Auth->authorize = 'controller';
$this->set('loggedIn', $this->Auth->user('id'));
}
function isAuthorized() {
return true;
}
}
login.ctp
<div class="midCol short">
<h3>Login</h3>
<div class="loginBox">
<?php e($form->create('User', array('controller'=>'users','action'=>'login')));?>
<?php
echo $this->Form->input('username');
echo $this->Form->input('password');
e($this->Form->end(array('label'=>'Login', 'class'=>'loginButton button png')));?>
</div>
</div>
Any help would be greatly appreciated, this has me tearing my hair out!
Just for documentation as I had difficulties finding an answer for CakePHP 2.x on the web. This stuff needs to be "correct" in order to use Form authentication:
The config needs to be right, e.g. in your UsersController (the fields config is really only required when names differ in the DB):
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'username',
'password' => 'password'
),
)
)
)
);
You have to use the Form Helper: Form->create adds a hidden input field ("post"), and the names of the input fields generated by Form->input() follow a convention that the Auth component expects.
User->login must not pass custom data to Auth->login(). The Auth component will take the auth data from the form (= request).
Thanks for the advice, but I ended up scrapping it and building again from scratch. Not exactly sure why it was originally breaking, probably not calling inbuilt functions with American English!
The Auth component will redirect to the page before you logged in. If that page was the login page that's where it'll redirect to.
When you're testing, it's likely that you're refreshing the login page, so on successful login that's where you're redirected to. You can check this by trying to perform an Auth protected action after logging in.
This gives me a lot of headaches as well - I think the current functionality of the component is a little clumsy in that respect.
I had the exact same problem and found that I had to restart mySQL service. Once it was restarted I stopped getting the login page being redirected. Hope that helps.
Gonna throw something in here. I was having an almost unresolveable problem with cakephp authentication. Ended up doing some debugging around it and found that during my database prep I had created a field for the password which was perfectly able to store normal size passwords... but.... when you start applying password hashing you need a lot more. My code was fine, but I had to add a bunch more space into the VARCHAR field for the password before I could log in. If you're having a problem with authentication - make sure your password field is adequately sized and not getting truncated like mine was. Took me a whole day to find that. DOH!
Correct me if i am wrong but must there not be code for redirection or something inside the function of login
function login() {
}
should it not be something like
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
}

Display custom validation messages using CakePHP $validate array

I'm trying to display custom messages like, 'this field should not be empty' or 'name not null' using the $validate array in the model. I have two controllers, main and users.
The index file of the main controller has the login and registration views. The action part of the login and register functions are in the user_controller. If the login and register function validate, they are redirected to the home page of the main controller,else they remain in the index page itself.
I want the validation messages to be displayed in the index page itself. But those messages appear only if there is a separate view file for login and register,i.e, /views/forms/register.ctp and /views/forms/login.ctp exist.
Is there a way to display those validation messages without having a separate view file for those functions? I have given my code below.Someone guide me please.
Model Class:
<?php
class User extends AppModel {
var $name = 'User';
var $components=array('Auth');
var $validate = array(
'name' => array(
'rule' => 'notEmpty',
'message' =>'Name cannot be null.'
),
'password' => array(
'rule' => 'notEmpty'
),
'email_id' => array(
'rule' => 'notEmpty'
)
);
function registerUser($data)
{
if (!empty($data))
{
$this->data['User']['name']=$data['User']['name'];
$this->data['User']['email_id']=$data['User']['email_id'];
$this->data['User']['password']=$data['User']['password'];
$existingUsers= $this->find('all');
foreach($existingUsers as $existingUser):
if($this->data['User']['email_id']==$existingUser['User']['email_id']){
return 0;
}
else{
$this->save($this->data);
$this->data['User']['id']= $this->find('all',array('fields' => array('User.id'),
'order' => 'User.id DESC'
));
$userId=$this->data['User']['id'][0]['User']['id'];
return $userId;
}
endforeach;
}
}
function loginUser($data)
{
$this->data['User']['email_id']=$data['User']['email_id'];
$this->data['User']['password']=$data['User']['password'];
$login=$this->find('all');
foreach($login as $form):
if($this->data['User']['email_id']==$form['User']['email_id'] && $this->data['User']['password']==$form['User']['password'])
{
$this->data['User']['id']= $this->find('all',array('fields' => array('User.id'),
'conditions'=>array('User.email_id'=> $this->data['User']['email_id'],'User.password'=>$this->data['User']['password'])
));
$userId=$this->data['User']['id'][0]['User']['id'];
return $userId;
}
endforeach;
}
}
?>
Controller Class:
<?php
class UsersController extends AppController
{
var $name = 'Users';
var $uses=array('Form','User','Attribute','Result');
var $helpers=array('Html','Ajax','Javascript','Form');
function register()
{
$this->Session->write('userId',$this->User->registerUser($this->data));
$this->User->data=$this->data;
if (!$this->User->validates())
{
$this->Session->setFlash('Please enter valid inputs');
$this->redirect('/main' );
return;
}
if($this->Session->read('userId')==0){
$this->Session->setFlash('You are already a registerd member.Log in your account');
$this->redirect('/main');
}
else{
$this->Session->setFlash('User account created');
$this->redirect('/main/home');
}
}
function login()
{
//$userId=$this->User->loginUser($this->data);
$this->Session->write('userId',$this->User->loginUser($this->data));
$this->User->data=$this->data;
if (!$this->User->validates())
{
$this->Session->setFlash('Please enter valid inputs');
$this->redirect('/main' );
return;
}
if($this->Session->read('userId')>0){
$this->Session->setFlash('Login Successful');
$this->redirect('/main/home');
break;
}
else{
$this->Session->setFlash('Username and password do not match.');
$this->redirect('/main');
}
}
}
?>
View Template:
<!-- File: /views/main/index.ctp-->
<div id="register">
<h3>Register</h3>
<?php
echo $form->create('User',array('action'=>'register'));
echo $form->input('name');
echo $form->input('email_id');
echo $form->input('password');
echo $form->end('Register');
?>
</div>
<div id="login">
<h3>Login</h3>
<?php
echo $form->create('User',array('action'=>'login'));
echo $form->input('email_id');
echo $form->input('password');
echo $form->end('Login');
?>
</div>
I think you're going about it the wrong way. You're doing way too much in the model, and you're also doing almost the same thing in the controller again after the fact. That's not good. Overall, honestly, the code is quite a mess for something so simple.
A huge WTF flag pops up here:
$existingUsers= $this->find('all');
foreach($existingUsers as $existingUser):
if($this->data['User']['email_id']==$existingUser['User']['email_id']){
You're seriously retrieving all users from the database (potentially a hugely expensive task) and then go through them one by one to compare a single field?!
You can simply define a validation rule that says 'email_id' should be unique, and Cake will automatically ask the database if the 'email_id' already exists. http://book.cakephp.org/view/472/isUnique
About your specific problem: You have the same form field twice on the same page, password and email_id fields for the same User model. There's no way for Cake to know which instance of the two fields is supposed to get the error message, they both have the same name. Also, I don't think you want to use validation error messages for the login form, you just want to see if the login was successful or not. Use Session::flash() instead to display an error message for a failed login, it's not field specific.
Take the login and register methods out of your model, they don't belong there. Only specify proper validation rules for the email, name and password fields in the model, they will automatically be checked upon calling $this->User->save() in the controller.
Don't hand-validate anything, unless there's really no way to do it with Cake validation rules (not the case here). If the built-in validation rules don't satisfy what you need to do, you can even make custom rules. http://book.cakephp.org/view/150/Custom-Validation-Rules
PS: Components are not for models. I think you need to learn more about the basics of Cake before continuing: http://book.cakephp.org/view/218/Tutorials-Examples
But, if you want to see your error messages that comes from the validate array you should access the $this->modelName->invalidFields() which will return you the fields that didn't pass the validation and the message that you have setted for them...

Resources