CakePHP 1.3 validation errors not showing with numerical indexed array - php

I've looked at loads of forums about validation errors not showing and tried various things but to no avail...
Basically, the validation is correctly recognising the fields do not have values when they should, however the error messages don't 'automagically' appear below the input boxes.
Model validation rule is shown below:
var $validate = array(
'description' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a description of the change'
)
);
echo pr($this->data); output is shown below:
Array
(
[Change] => Array
(
[0] => Array
(
[id] => 3237
[cn_id] => 5132
[req_id] => 25
[description] =>
)
[1] => Array
(
[id] => 3238
[cn_id] => 5132
[req_id] => 22
[description] =>
)
[2] => Array
(
[id] => 3239
[cn_id] => 5132
[req_id] => 4
[description] =>
)
)
)
echo pr($this->Change->invalidFields()); output is shown below:
Array
(
[0] => Array
(
[description] => Please enter a description of the change
)
[1] => Array
(
[description] => Please enter a description of the change
)
[2] => Array
(
[description] => Please enter a description of the change
)
[description] => Please enter a description of the change
)
So, it is generating the errors messages for display, but they don't actually display in the view, and I don't know why?
Excerpt from the 'view' code is show below:
<?php echo $form->input('Change.'.$i.'.description',
array('value' => $cn['Change'][$i]['description'],
'label' => $engReq['Req']['description'])); ?>
Does anybody have ideas why the error messages are not showing?

I experienced the same issue with a hasMany model (where the form had numerically indexed fields) and came up with a validation solution that worked for me.
Quick answer: Before trying to actually save the data, I validated the data separately like (notice 'validate'=>'only'):
if($this->ModelName->saveAll($this->data, array('validate' => 'only'))) {
// proceed to save...
}
Doing it this way gave me the model's validation error message in the form, right under the input field that failed the validation (the normal Cake way of showing the validation error).
Note: I could not use saveAll() to actually save my data (I'll explain why in a minute). If I could use saveAll() to actually save the data, I could have gotten the validation at the same time as I saved by using (notice 'validate' => 'first'):
if($this->ModelName->saveAll($this->data, array('validate' => 'first')))
However, I could not use saveAll() to actually save the data, due to the fact that I needed to use a transaction to save several models at once, where some of the models were not directly related to other models. saveAll() will only save the model on which it is called, plus models directly related to it. Since Cake does not currently support nested transactions, and saveAll() uses one transaction automatically, I had to use save() on my models and start and end my transaction manually. However, this caused me to loose the validation message in my form on the hasMany items, even if I saved by using "$this->ModelName->save($this->data, array('validate'=>'first')".
Further explanation: The issue does seem to be related to using numerically indexed fields in the form. For example:
$this->Form->input("ModelName.0.field_name");
It seems this indexing scheme is the proper way to handle hasMany items in the form, but the validation messages would not find their way to this form input. It is interesting to notice that my view did in fact have access to the validation error. This can be seen in the view by using (notice no numerical index in these lines):
if($this->Form->isFieldError("ModelName.field_name")) {
echo $this->Form->error("ModelName.field_name");
}
Putting these lines after the '$this->Form->input("ModelName.0.field_name")' inserted a the validation message into the page, just not in the same div as the input field (and thus it didn't look ideal).
I couldn't figure out a way to tell Cake to use that validation message in the '$this->Form->input("ModelName.0.field_name")'. So I resorted to the 'validate' => 'only' method described earlier, which is working well for me.

shouldnt it be
var $validate = array(
'description' => array(
'notEmpty' => array(
'rule' => 'notEmpty',
'required' => true,
'allowEmpty' => false,
'message' => 'Please enter a description of the change'
)
)
);
?

Related

Zend 2 Form Validator 'InArray' - Complicated array returning invalid

I am trying to implement the 'InArray' validator in Zend 2 on a form and it keeps on returning invalid. Here is the code:
The Form Element setup:
$enquiryType = new Element\Select('enquiryType');
$enquiryType->setLabel('* What is your enquiry about?')
->setLabelAttributes(array('class' => 'sq-form-question-title'))
->setAttribute('class', 'sq-form-field required')
->setValueOptions($enquiryTypes);
The Filter/Validator setup:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes));
And here is the array that gets passed into $enquiryTypes via the module.config.php file
'enquiryCategories' => array(
'empty_option' => 'Please select an option',
array(
'label' => 'General enquiries',
'options' => array(
'skype' => 'Skype with your library feedback',
'question' => 'Ask a question',
'feedback' => 'Library feedback',
'eresource' => 'Electronic resources (e.g. e-book, e-journal, database)',
'webbridge' => 'WebBridge Problems',
'dro' => 'DRO'
)
),
array(
'label' => 'Application to review',
'options' => array(
'10400' => 'I\'ve returned the item',
'10401' => 'I didn\'t know about overdue points but now I have some',
'10402' => 'Why did I get this invoice?',
'10403' => 'The item I borrowed is lost',
'10404' => 'The item I borrowed has been damaged',
'10405' => 'I never got/had the book',
'10406' => 'Other'
)
)
),
I have tried different variations of this (using the recursive validation also) but have not been able to work this out.
One thing that I'd try, is as follows:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes['enquiryCategories']));
The reason I say that, is that it looks like you might be creating an array inside of the array perhaps. Unless I've misunderstood the description.
If that isn't working for you then maybe you might need to explore the Explode option as pointed out in the following question
ZF2: How do I use InArray validator to validate Multiselect form element?
Good luck.
I finally got a working solution for this. I feel there should be a better solution but I could not find one.
Here is the filter I used:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => array_keys(
$enquiryTypes[0]['options']+$enquiryTypes[1]['options']
)));
$enquiryType->getFilterChain()
->attach(new Filter\StringToLower())
->attachByName('StripTags');
Basically I had to disect the array options into a straight associative array. As the array remains static in this instance then this works well.
If the data becomes dynamic then something more would be required (loop through and find the 'option' key, add children to filter array etc...)

CakePHP Saving a new normalized HABTM model and using it in the resolved table

So quick overview of what I'm trying to do. User hasMany BusinessUnitsUser. BusinessUnit hasMany BusinessUnitUser.
In this manner, I've normalized their relationship to two hasManys (I hate working with HABTM related data).
On a new user form, I'd like to give the user the option of adding a new Business Unit at the same time.
Currently, my $this->request->data array looks like this:
Array
(
[User] => Array
(
[title] => Mr
[first_name] => Kyle
[last_name] => O'Brien
[username] => 55546#mylife.unisa.ac.za
[producing_office_id] => 4
)
[BusinessUnit] => Array
(
[name] => lskfjsldkfjsdlfk
)
)
Now, this is obviously incorrect, but I'm struggling to think of how to resolve this. I thought giving you a visual of the array, you might be able to tell me what my array should look like.
Here's my relationship array in BusinessUnitsUser:
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'BusinessUnit' => array(
'className' => 'BusinessUnit',
'foreignKey' => 'business_unit_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
EDIT (thanks ndm)
Note the goal: I'm adding a user and I may or may not be adding BusinessUnitsUser associations as well but I'm definitely also going to be adding a new BusinessUnit - the form for which exists on the new_user form.
Currently, the User is saving with a $this->User->saveAll($this->request->data) but NOT the new BusinessUnit and certainly not the new BusinessUnitsUser entry (which I expect to contain the new user id and the new business unit id.
Save via the join table model
The solution should be pretty simple, for that type of association you'll have to save via the join table model (even if you don't save additional data on the that table):
$this->User->BusinessUnitsUser->saveAssociated($this->request->data);
See also http://book.cakephp.org/.../saving-your-data.html#saving-hasmany-through-data
That way the ORM can properly save the belongsTo associated data, and create an appropriate record in the join table, using foreign key values obtained from the save operations for the associated data.

MongoDB - PHP manual references approach suitability

MongoDB newbie here. I'm having the first approach on references, and my main doubt is if i'am using the appropriate strategy(manual references) for my situation.
Working on 2 collections(user, message) in the same db, lets make an example of a document stored in user collection:
array (
'_id' => new MongoId("5231817277758e660c7202c4"),
'uname' => 'pluto',
'pwd' => new MongoInt32(1234567),
'email' => 'pluto1#gmail.com',
'phone_home' => new MongoInt64(23409238),
'phone_work' => new MongoInt64(54389724),
'phone_mobile' => new MongoInt64(9823422),
'visible' => new MongoInt32(1),
)
and an example of a document stored in message collection (sent FROM an other user TO the user above 'pluto'):
array (
'_id' => new MongoId("524358102660b2c70b8b4567"),
'from_uid' => '5231817277758e660c7202d7',
'to_uid' => '5231817277758e660c7202c4',
'object' => 'mongo manual Ref',
'content' => 'is that the correct approach?',
'datetime' => '2013-09-25 23:39:28',
)
The user logged in ('pluto') can see all the messages he received from other users but, i don't wat to print the 'from_uid' value, i want to replace it with the username of the sender.
My main doubt is if manual references is the right approach for this scenario, because with this technique(if i havn't miss understood everything), print a list of message would involve:
the 'query' for print the list of messages
an other 'query' for retrieve the username from the other collection, for each messages. Also if a user have received 1000 messages, this approach will have to run 1001 query??
My secondary doubt is if there is a way for directly merge or replace the result of two cursors
Given your use case it would probably be ok to duplicate a little bit of data and store some of the necessary fields about the sending user as an embedded document - in this case, the username.
array (
'_id' => new MongoId("524358102660b2c70b8b4567"),
'from_user' => array(
'uid' => '5231817277758e660c7202d7',
'uname' => 'mars'
),
'to_uid' => '5231817277758e660c7202c4',
'object' => 'mongo manual Ref',
'content' => 'is that the correct approach?',
'datetime' => '2013-09-25 23:39:28',
)
This approach means that when you query for messages to a user ( in which you already know the to_uid), you get all of the messages with the correct id to the from_user, but also already have their username to display.
Now, instead of querying 1000+ times, you only need to query when there is more information needed about a user - such as fetching their profile, etc...

Autofill Office Phone in SugarCRM Contact Module

Can anyone tell me how I can have an office phone automatically fill in a Contact when we select an Account name?
It should do that automatically. Look in /modules/Contacts/metadata/editviewdefs.php, and you should see the following.
array (
'name' => 'account_name',
'displayParams' =>
array (
'key' => 'billing',
'copy' => 'primary',
'billingKey' => 'primary',
'additionalFields' =>
array (
'phone_office' => 'phone_work',
),
),
i use version 5.3.3. I want to do the same thing with a small difference. when i am in an account and i want to create a quote, some information like billing address… transfer automatically but my custom field not…
I add in /modules/Accounts/metadata/editviewdefs.php this part of code:
2 =>
array (
0 =>
array (
‘name’ => ‘afm2_c’,
‘label’ => ‘LBL_AFM2’,
‘displayParams’ =>
array(
‘afm_timologisis_c’=> array(
‘name’ => ‘afm2_c’,
),
),
),
I want the value afm_timilogisis_c (quotes) to have the same value with afm2_c (accounts). That happens when i create a quote in an account with the address fields.
It doesn’t work with my custom fiels? Is anything false? Must i add this code in another folder-file? Must i change anything?
Thanks

what can cause $model->attributes to not get correct values in Yii?

I have these lines in my actionCreate:
if (isset($_POST['DpcioCbn'])) {
print_r($_POST['DpcioCbn']);
$model->attributes = $_POST['DpcioCbn'];
print_r($model->attributes);
die();
...
}
which return this:
Array
(
[code] => 34324
[bn_fa] => dfsf
[bn_en] => sdf
[cbn_fa] => sdfds
[cbn_en] => f
[description] => dsfsdfsdf
[update_at] => 1391-03-16
[active] => 1
)
Array
(
[active] => 1
[code] => 34324
[bn_fa] => dfsf
[bn_en] => sdf
[cbn_fa] => sdfds
[cbn_en] => f
[update_at] => 1391-03-16
[id] =>
[description] =>
)
what happens for description field? is there any thing about this assignment is Yii?
I found that there is a term in yii around this type of assignments: Massive Assignment .So I should explicitly define validation for each fields to make Massive Assignment.
public function rules() {
return array(
...
array('description', 'safe'),
...
);
}
http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/#hh2
For some fields, there's nothing to validate, right?
Wrong: by only assigning field values that the user has explicitly
said are eligible for copying into $model, this limits shenanigans of
a bad guy trying to pollute a model.
Even if a field has no particular data-format validations, we still
have to tell Yii we want the attribute copied during Massive
Assignment. This is done with the 'safe' validator.
Wrong: by only assigning field values that the user has explicitly said are eligible for copying into $model, this limits shenanigans of a bad guy trying to pollute a model.
Even if a field has no particular data-format validations, we still have to tell Yii we want the attribute copied during Massive Assignment. This is done with the 'safe' validator.
http://www.jili.ir

Categories