validation is always true in cakephp - php

Im new to cakePHP and tried to create a simple user registration. Now I'm stuck since two days in the validation of the form. The validation function returns always true and so the form is always saved to the database, even if it is empty.
So here are the model, the controller and the view. Maybe you can see what I did wrong here?
/app/Model/MemberModel.php
<?php
class Member extends AppModel {
var $validate = array(
"username" => array(
"rule" => "alphaNumeric",
"allowEmpty" => false
)
);
}
?>
/app/Controller/MemberController.php
<?php
class MemberController extends AppController {
var $components = array("Security");
var $helpers = array("Html", "Form");
public function index() {
}
public function register() {
if($this->request->is("post")) {
Security::setHash("blowfish");
$this->Member->set($this->request->data);
debug($this->Member->validates());
if($this->Member->save(array("password" => Security::hash($this->request->data["Member"]["password"])))) {
$this->Session->setFlash(__("Saved."));
} else {
$this->Session->setFlash(__("Error: ").$this->validationErrors);
}
}
}
}
?>
/app/View/Member/register.ctp
<?php
echo $this->Form->create("Member");
echo $this->Form->input("username");
echo $this->Form->input("password");
echo $this->Form->end("Register");
?>

Oh, I just realized your problem.
/app/Model/MemberModel.php
should be
/app/Model/Member.php
The controller will look for Member.php, and if it can't find it, it will try the default $validate behavior in AppModel

Related

How to point to a different Controller of a Model in CakePHP

I have one Model class named 'Name' and one Controller class named 'Controller1'. I have created a form using 'Name' model which is by default pointing to 'names' controller as per default naming convention of cakephp. But i want it to point to 'Controller1' controller..
I've replace this code:-
<?php echo $this->Form->create('Name'); ?>
with this one to see if it works:-
<?php
echo $this->Form->create('Name',array('controller'=>'Controller1',
'action'=>'view'));
?>
But it is not working and is pointing to 'names' controller only.
How can i point it to 'Controller1' instead of 'names' controller?
More details:-
Model (Name.php):-
class Name extends AppModel{
public $useTable = "tbl_names";
}
Controller (Controller1Controller.php):-
class Controller1Controller extends AppController
{
public function index(){
}
public function view($id){
$name ='';
if($this->request->is('post')){
$name = $this->request->data('name');
if($name==="xyz"){
$this->redirect('http://www.google.com');
}else{
$this->Save($this->request->data);
$this->request->data['name']= 'Nice';
}
}
return $id;
}
// Save to database if entered name is other than 'xyz'
private function Save($data){
$this->Name->create();
}
public function viewname($id,$name){
}
}
You have to set url key to pass crontroller and action values.
echo $this->Form->create(false, array(
'url' => array('controller' => 'recipes', 'action' => 'add'),
'id' => 'RecipesAdd'
));
See FormHelper > Options for create()

CakePHP 2 testing model with no table using mock method for email

I'm attempting to write a test for a model that has no table but sends an email if the data passes validation in CakePHP 2.
To test I want to assert that some data passes validation and would therefore send an email without actually sending one. For this I am attempting to create a mock method for CakeEmail. However, the test is failing because $useDbConfig hasn't be defined for the mock method:-
Undefined property: Mock_MyModel_7a1fb8d0::$useDbConfig
I assume this is an issue with the model not having a table, but cannot see how to resolve it.
My model looks something like (excluding the validation rules):-
<?php
App::uses('CakeEmail', 'Network/Email');
class MyModel extends AppModel {
public $useTable = false;
public function send($data) {
$this->set($data);
if ($this->validates() === false) {
return false;
} else {
$Email = $this->getEmailer();
$Email->from($data['MyModel']['email_from']);
$Email->to($data['MyModel']['email_to']);
$Email->subject($data['MyModel']['subject']);
$Email->send($data['MyModel']['message']);
}
return true;
}
public function getEmailer() {
return new CakeEmail();
}
}
My test is:-
<?php
class MyModel extends CakeTestCase {
public function setUp() {
parent::setUp();
$this->MyModel = ClassRegistry::init('MyModel');
}
public function testSend() {
$emailer = $this->getMock(
'CakeEmail',
array(
'to',
'emailFormat',
'subject',
'replyTo',
'from',
'template',
'viewVars',
'send'
)
);
$emailer->expects($this->any())->method('send')->will($this->returnValue(true));
$MyModel = $this->getMockForModel('MyModel', array('getEmailer'));
$MyModel->expects($this->once())->method('getEmailer')->will($this->returnValue($emailer));
$data = array(
'MyModel' => array(
'email_to' => 'foo#example.com',
'email_from' => 'bar#example.com',
'subject' => 'Foo bar',
'message' => ''
)
);
$result = $MyModel->send($data);
$this->assertTrue($result);
}
}
Any help would be appreciated. This is the first time I've tried/needed to mock a method in Cake using tests.
Class name should have been MyModelTest rather than MyModel. CakePHP's naming convention needs to be adhered to.

Zend - Accessing datas from form from another controller by a view helper

after some questions about how to resolve one of my problem (http://stackoverflow.com/questions/13609611/using-several-modules-in-the-same-view) I have another one.
I made a form in a view helper because I needed to access the result of this form in another controller.
So here is my view helper called QuickSearch.php
class Zend_View_Helper_QuickSearch extends Zend_View_Helper_Abstract
{
public function quickSearch()
{
$form = new Application_Form_QuickSearchForm();
return $form;
}
}
calling QuickSearchForm.php
class Application_Form_QuickSearchForm extends Zend_Form
{
public function init()
{
$this->setMethod('post');
$this->setAction('/search/quicksearch');
$this->addElement('text', 'searchLocation', array(
'label' => 'Location:',
'required' => true,
'filters' => array('StringToUpper')
));
//[some other elements]
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Search',
));
}
In my main page view, I call the viewhelper with
echo $this->quickSearch();
Which works, since I have access to my form.
When I submit my form, the /search/quicksearch is called as it's supposed to be but when I try to access the data from the form, it seems that it's empty.
Here is my Search controller (SearchController.php)
class SearchController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
}
public function quicksearchAction()
{
$form = new Application_Form_QuickSearchForm();
if ($this->getRequest()->isPost())
{
echo("post");
$data = $form->getValues();
echo($data['searchLocation']);
}
}
}
I put the echo("post") to see if I was getting a POST request, and every time it works.
the only thing that display is the 'post' and the second echo doesn't display anything.
I don't know what I didn't understand in the way to get the form's data from another controller.
Can someone help me with this ? I just don't know why it doesn't work.
You need to pass the post data to the form object. The typical way to do this is by calling the isValid() method of the form (which also validates the submitted data):
public function quicksearchAction()
{
$form = new Application_Form_QuickSearchForm();
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()) {
$data = $form->getValues();
echo $data['searchLocation'];
}
}
}

Posting to a controller with ajax in CakePHP 2.0

When I post to this controller, I get this back as the response: Fatal error: Call to a member function find() on a non-object in /app/Controller/AppController.php on line 26 which probably has to do with using $this->data() explicitly. I was using CakePHP save without form
per a recommendation in there, but since I'm not using a form to send the data (thus not using $this->request->data()), I'd like to know what the replacement is for $this->data() so I can get this working.
My database table is is submissions_favorites.
This is my SubmissionFavorite model:
class SubmissionFavorite extends AppModel {
var $name = 'SubmissionFavorite';
var $belongsTo = array(
'User' => array(
'className' => 'User'
)
);
}
This is AjaxController (what I'm posting to):
class AjaxController extends AppController {
var $layout = 'ajax'; // uses an empty layout
var $autoRender = false; // renders nothing by default
var $uses = 'SubmissionFavorite';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->loginRedirect = array('controller' => 'home', 'action' => 'index');
$this->Auth->allow('addFavorite');
$this->Auth->flashElement = 'flash_error';
}
public function addFavorite() {
$this->autoRender = false;
$this->data['SubmissionFavorite']['user_id'] = $this->Session->read('Auth.User.id');
$this->data['SubmissionFavorite']['submission_id'] = $_POST['id'];
$this->data['SubmissionFavorite']['when'] = DboSource::expression('NOW()');
$message = array('success' => 'success');
$toReturn = json_encode($message);
if ($this->RequestHandler->isAjax()) {
if ($this->Session->read('Auth.User')) {
$this->SubmissionFavorite->save($this->data);
return $toReturn;
} else {
$login = array('login' => 'Please log in to add favorites');
return json_encode($login);
}
}
}
Line 26 in my AppController is:
protected function getSubmissionCount() {
$totalSubmissions = $this->Submission->find('count');
return $totalSubmissions;
}
Which is totally unrelated to anything else. I didn't even add anything to AppController when I wrote the new method within my AjaxController, so I'm not sure how it's relevant (or why I'm even getting an error in that file).
First, following cake conventions, you should name your model SubmissionsFavorite (note the s between Submission and Favorite). This is because your table name is composed by 2 words, even representing a relationship between 2 other tables.
Also, you can't do $this->Submission->... on AppController without telling cake whatever is "Submission". Take a look at this link to see how to initialize Submission model and use it on AppController: Can I use one model inside of a different model in CakePHP?
Regards.
Try to change all
var $name = 'SubmissionFavorite';
to:
public $name = 'SubmissionFavorite';
Also change: var $uses = 'SubmissionFavorite';
to: public $uses = array ('SubmissionFavorite');

Using custom isValid() function for specific subform in Zend_Form

I have a form with several subforms. I've overriden the form's isValid function with my own, but can't find any documentation on how to set an isValid function per individual subform.
Can someone post a link or sample code so I can learn how to do this please.
Thanks in advance.
<?php
class Your_Sub_Form extends Zend_Form_SubForm
{
public function isValid($data)
{
// Your custom validation-logic here
return parent::isValid($data);
}
public function init()
{
...
}
}
class Your_Form extends Zend_Form
{
public function isValid($data)
{
return parent::isValid($data);
}
public function init()
{
$this->addSubForm(new Your_Sub_Form(), 'subform');
$this->addElement('submit', 'submit', array(
'ignore' => true,
'label' => 'Submit',
));
}
}
$form1 = new ..._Form1();
$form2 = new ..._Form2();
if ($form1->isValid($this->getRequest()->getPost())) {
...
}
if ($form2->isValid($this->getRequest()->getPost())) {
...
}
Try using Zend_Validate_Callback http://framework.zend.com/manual/en/zend.validate.set.html to validate just the special fields you want. You can access other field values through the context.

Categories