CakePHP 1.3 controller save() does not save data - cakephp

I want to add a new user to the database, and do so by making them fill in a form and submitting this. All seems to work fine. Just before my save() call in the controller I return all data and all necessary data is there. It is valid(ated), since no errors are returned.
But then nothing happens. I'm being returned to my form without any errors being shown.
This is my 'save-line':
if($this->Registratie->save($this->data)) {
I'm not making use of any beforeSave() methods.
Using debug($this->validationErrors); shows:
app/controllers/registratie_controller.php (line 45)
Which is the line of code from above.
I've been going through my code over and over. What could the problem be?

When you create a form using the FormHelper it will generate input names like:
<input type='text' name='data[Registratie][first_name]'>
Once the form is submitted cake will push that into the $this->data array with an index of 'Registratie'
You probably need to pass the index to the model when saving
if ($this->Registratie->save( $this->data['Registratie'] ) ) {
I would also do a var_dump($this->data) or print_r($this->data) to make sure your form fields are coming through.

I had the same problem, fixed doing exactly what Jack B Nimble told. Using CakePHP 1.3
Sample:
Model: Contacts
$this->data['contact']

Related

CakePHP 3 How to detect if an entity field is changed

I'm developing a CakePHP 3 application.
Now, i need to encrypt some data with SHA1 before the save of the entity.
I tried the beforeSave() callback in Table Object, like in CakePHP 2.x, but it doesn't work.
So, i discovered that type of change (update data on beforeSave/beforeUpdate) in current version, needs to be adapted to accessors & mutators, like the docs says (http://book.cakephp.org/3.0/en/orm/entities.html#accessors-mutators).
Documentation even has a note about check if an entity field was modified (http://book.cakephp.org/3.0/en/orm/entities.html#checking-if-an-entity-has-been-modified) but i dont understand how to use this.
I need some simple logic, just like an authentication system.
Before Save, in User Model, the field responsible_card_password must be hashed with SHA1 if this is filled. If isnt filled, the field stays the same.
Currently, with the acessors and mutators method, if i put the field on form blank, the entity save this field blank.
How i can solve this? Very thanks CakePHP developers on the world! :-D
you can add code in your entity table to auto hashing password
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}

CAKEPHP Do I have to set $this->data in the controller for it to work with the form helper

I would like to set $this->data in a view rather than the controller. Will this work with the form helper to automagically input values?
many thanks!
Further explanation if you really want to know...
You may wonder why I wouldn't just put the values right into the value field but it makes sense in this situation to put it into $this->data; I have a ton of fields of various types and I do not want to have to add if isset() to every value field because form fields are generated based on a stored value and may or may not have already been filled in. I cannot set this->data in the controller because of the data being in JSON. Plus the data has to go through several layers before getting to where it is at this point.
unresolved but I got around it by entering everything manually. It would have been nice to add it automagically.

Form validation for relational elements

I have a form in CakePHP to save information to multiple models.
My first model is "World", I have no problem for these fields the validation is correct and it's saved correctly to the database.
The second model is "Country", I use something like this:
echo $this->Form->input('Country.0.name');
This is correctly saved to the database, but there is no validation (like stairs for required fields) and no automagic (autodetection of the content type).
The third model is "Region", I use the same code as for the second one but there is no validation, no automagic and no saving...
Can someone help ?
Thank you,
Sébastien
Without seeing the rest of your code, I am guessing that you are trying to save multiple countries at the same time. The model expects the data to come in a specific format:
$this->data['Model']['field'];
What you are passing is:
$this->data['Model'][0]['field'];
The model cannot interpret it. The way to resolve this is build a foreach when you collect the data and send each request independently.
foreach($country as $field) {
$data['Country']['field'] = $field;
// add other fields that are required
if($this->Country->validates($data)) {
$this->Country->create();
$this->Country->save($data);
} else {
// error handling
}
}
Good luck and happy coding!

How do you perform Form validation without a model in Cakephp?

I need to perform some validation. I don't have the model in the application.
Does anyone know how to do the validation without a model?
Can you show me using a small sample or statement?
Honestly, I'd create a model just for the validation. You can create a model that doesn't use a table by adding
var $useTable = false;
And then create a validation array with rules for each field you want to validate:
var $validate = array('login' => 'alphaNumeric','email' => 'email','born' => 'date');
Then, in your controller, do something like:
$this->MyModel->set($this->data);
if($this->MyModel->validates()){
// do stuff with valid data
}
If you really, really can't use a model, then you'll have to simply loop over each value in $this->data in your controller action and validate it against a regular expression or use the Validation::[rule]() stuff, like:
if(Validation::email($someThingThatMightBeAnEmailAddress)){
// do stuff with valid email address.
}
You can perform validation of form data in CakePHP without having to create a model.php file. There are many times when I need to do this, and storing model.php files that do nothing more then validation is a poor usage of the model design pattern.
Another problem with CakePHP is that sometimes validation rules are common across multiple models. It would be nice to move validation out of the model, much in the way behaviors are to their own subfolder. That way we can re-use them or use them without a model.
Another problem with validation is that it's dependent upon the model alias. If you have a model called "Email" without a table to perform validation, then the posted form must also use "Email". If the form uses a alias different from the controller, then you have to set the action. A lot of extra steps just to do validation. You can't re-use that model again if your form uses a different model.
So here is my alternative approach.
In your controller's action that receives the posted form data. You can create a default CakePHP model, add some validation rules and then use that model for validation.
An example action might look like this;
function edit()
{
$model = ClassRegistry::init(array('class'=>'Email','table'=>false,'type'=>'Model'));
if(!empty($this->data))
{
$model->validate = array(
'subject'=>array(
'rule'=>'notEmpty',
'required'=>true
),
'message'=>array(
'rule'=>'notEmpty',
'required'=>true
)
);
if($model->save($this->data))
{
// validation was successful, but no data was actually saved
}
}
}
The key here is the creation of an automatic model by CakePHP.
$model = ClassRegistry::init(array('class'=>'Email','table'=>false,'type'=>'Model'));
The above attempts to find a model by Email in the applications model folder. When it is not found CakePHP will auto-create an in memory model for that class. Since we set the value of 'table' to false, then this should tell CakePHP that this model doesn't use a table.
This works as long as there really isn't a email.php file in the applications model folder. Once this model is created in memory. It's accessible from the built in Form help. That means validation errors will be passed correctly to the view.
Here is an example view file.
<?php echo $this->Form->create('Email',array('action'=>array('controller'=>'mycontroller','action'=>'edit'))); ?>
<?php echo $this->Form->input('subject'); ?>
<?php echo $this->Form->input('message',array('type'=>'textarea')); ?>
<?php echo $this->Form->submit(); ?>
The view will now render the validation errors from the Email model using the Form helper. This is because CakePHP class registry has saved a copy of the EMail auto model in memory that the Form helper will access.
If you want to use custom validation rules, then you will have to put the callback methods in the app_model.php file.
These methods tested in CakePHP 1.3
#ThinkingMedia's answer got me going in the right direction, but $model->save($this->data) was returning false for me unfortunately, even when the form was valid. I'm using CakePHP 2.3.9 for reference.
It turned out that even with 'table' => false parameter set, the returned$success of save() was based on a $count > 0 of the rows that were created/updated/modified. In my table-less case, this meant a $count of 0 and $success was false. I ended up blending the referenced answer with this similar question's solution to have validation work properly without a model file:
function edit()
{
$model = ClassRegistry::init(array('class'=>'YourFormName','table'=>false,'type'=>'Model'));
if($this->request-is('post'))
{
$model->validate = array(
'some_field'=>array(
'rule'=>'notEmpty',
'required'=>true
),
'another_field'=>array(
'rule'=>'notEmpty',
'required'=>true
)
);
$model->set($this->request->data)
if($model->validates($this->request->data) && empty($model->validationErrors))
{
// validation was successful, but no data was actually saved
}
}
}
Came across this question since I also had a similar issue. I have a form that needs to collect data and generate a PDF. So there is no data saving involved nor there is a maching model class. The PDF is a user contract and the user will fill the online form and the data filled will be used to generate the PDF which they must print and mail back. But I need to validate whether the fields are not empty, whether email is really an email format, and date inputs are really date inputs.
First I did without a model class then saw this quesion. Now I'm using a dummy model class to have my validations put in there since the code in controller action looks much neat.
Class Validation which is a subclass of Object is used by model class to perform validation against validation rules specified in it.
One can directly instantiate Validation class inside any controller or model and use its methods for performing validation on any data, not only inputs from forms.
I think my first question would be this: if you don't have a model...what are you validating? Typically data collection would be done to populate a model. If you're using an alternative data repository (file, web services, etc.), a model would still be the appropriate way to access and manipulate that data.
In short, in order to better answer this, I think a little more context would be helpful and maybe even necessary.

CakePHP: Passing $this->data to the View from Controller

I'm using CakePHP 1.2 and I'm just wondering if there is any side affect on passing the $this->data to the View from the Controller.
Ex:
// inside PostsController, I have this code:
$this->data['Posts'] = $this->Post->find('all');
instead of :
$posts = $this->Post->find('all');
$this->set(compact('posts'));
// inside the /posts/view, I access it like this:
<?php foreach ($this->data['Posts'] as $post) {....};?>
By doing this, I skipped the $this->set() from the controller all together. Does this violate any MVC pattern or any security issue that I might have overlook? I saw that using the Auth Component, $this->data contains the [_Token] array.
Thanks
You need to be aware of the different places that Cake Helpers automagically look for data, since that is were it makes a real difference. The Form Helper will fill in fields automatically based on the contents of $this->data. That's how form data persists when validation fails. OTOH, a <select> elements options array is automatically taken from the pluralized field name,
e.g. $form->select('Model.foo_id') will take its options from $foos if set.
As such, $this->data has its special place and shouldn't be used lightly, just as named variables have their use and shouldn't be ignored. Use both as appropriate. If you don't want to auto-set Form Helper content, set() your variables. IMHO it's also more readable to assign a variable name that hints at the data it contains. All your views operating on $this->data is less clear than one view operating on $foo and another on $bar.
In CakePHP 2.x you should use $this->request->data instead if plain $this->data, otherwise you might end up getting this error:
Indirect modification of overloaded property View::$data has no effect
$controller->data is meant for data posted to the control from view file.
$view->data is for general data.
I would avoid doing it to keep myself sane. besides you are typing more in view.
There is no good reason for setting $this->data directly except when working with forms.
Why break convention - Controller:set is there for a reason. If you want to pass data to the view for display or display logic purposes you should use the function provided instead of trying to co-opt Controller:data for unintended purposes.
Everything is easier from within CakePHP if you follow the rules and do things the expected, correct way.
In cakephp version 2.*, error occurs when you try to set data on $this->data

Resources