http://magento.localhost.com/index.php/arithmetic/adminhtml_arithmetic/edit/id/5/key/c03c12d4c338a2e4cdbb93c3d9e511a93401d19b21a13ea77cffda20cac94577/
This is what my link looks like. I am getting all values by the ID, in the edit grid page
there is a section for multiple check boxes. How can I select all the check boxes according to the result array
$fieldset-> addField('st_user_interest', 'checkboxes', array(
'label' => Mage::helper('arithmetic')->__('Interest'),
'required' => true,
'name' => 'st_user_interest[]',
'values' => array(
array(
'label' => Mage::helper('arithmetic')->__('Education'),
'value' => 'education',
'class' => 'required-one',
),
array(
'label' => Mage::helper('arithmetic')->__('Business'),
'value' => 'business',
'class' => 'required-one',
),
array(
'label' => Mage::helper('arithmetic')->__('Marketing'),
'value' => 'marketing',
'class' => 'required-one',
),
array(
'value' => 'investment',
'label' => Mage::helper('arithmetic')->__('Investment'),
'class' => 'required-one',
)
),
));
Thanks
Hi at the time of storing array field value we are storing as string after converting array to string,
So at the time of setValues() Magento looking for that same input field value as array to check the check boxes
Trick is that convert that stored string value into array and assign to that column field that will work
Package_Arithmetic_Block_Adminhtml_Arithmetic_Edit_Tab_Form
protected function _prepareForm()
{
$id = $this->htmlEscape(Mage::registry('arithmetic_data')->getIn_user_id());
$model = Mage::getModel("arithmeti/newuser")->load($id);
/* here is the stuff witch converting the stored string to array and set in st_user_interest */
$interest = $model->getSt_user_interest();
$model->setSt_user_interest(explode(',',$interest));
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('arithmetic_form', array('legend'=>Mage::helper('arithmetic')->__('User information')));
$fieldset-> addField('st_user_interest', 'checkboxes', array(
'label' => Mage::helper('arithmetic')->__('Interest'),
'required' => true,
'name' => 'st_user_interest[]',
'values' => array(
array(
'label' => Mage::helper('arithmetic')->__('Education'),
'value' => 'education',
),
array(
'label' => Mage::helper('arithmetic')->__('Business'),
'value' => 'business',
),
array(
'label' => Mage::helper('arithmetic')->__('Marketing'),
'value' => 'marketing',
),
array(
'value' => 'investment',
'label' => Mage::helper('arithmetic')->__('Investment'),
)
),
));
if ( Mage::getSingleton('adminhtml/session')->getArithmeticData() )
{
$form->setValues(Mage::getSingleton('adminhtml/session')->getArithmeticData());
Mage::getSingleton('adminhtml/session')->setArithmeticData(null);
} elseif ( $model->getData() ) {
//Mage::registry('arithmetic_data')->getData(); /* removing this line and adding $model->getData() inslde the $form->setValues() */
$form->setValues($model->getData());
}
return parent::_prepareForm();
}
Related
I would like to remove the empty or first option of list data value. I have FruitList model and it has a list, so I need to prevent from users to select all.
But now the problem is the empty option that can let user to select all Fruits, so how can I remove.
This is my code
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'header' => 'Buyer',
'name' => 'Buyer',
'value' => 'customer_name',
'filter' => $fruits
),
array(
'header' => 'Fruits',
'name' => 'fruit_id',
'value' => '$data->Buyers->FruitList->Name',
'filter' => $fruits
),
array(
'class'=>'CButtonColumn',
),
),
));
By default filters for CGridView renders dropdown with empty option to allow disabling filtering. But you can overwriting this behavior by providing your own dropdown as a filter:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'header' => 'Buyer',
'name' => 'Buyer',
'value' => 'customer_name',
'filter' => CHtml::activeDropDownList($model, 'customer_name', $fruits),
),
array(
'header' => 'Fruits',
'name' => 'fruit_id',
'value' => '$data->Buyers->FruitList->Name',
'filter' => CHtml::activeDropDownList($model, 'fruit_id', $fruits)
),
array(
'class'=>'CButtonColumn',
),
),
));
Make sure that you set default value for these filters in your model - something like this in your controller:
// ...
$model->fruit_id = FruitList::DEFAULT_ID;
$model->customer_name = FruitList::DEFAULT_ID;
if (isset($_GET['FruitList'])) {
$model->setAttributes($_GET['FruitList']);
}
$dataProvider = $model->search();
// ...
you can set condition in the dataProvider so its return you a result of all not null value.for example
$dataProvider->criteria->addCondition('fruit_id IS NOT NULL ');
I hope its work!
Folks,
I'm trying to ensure at least one of two fields (last_name or email) is being populated. Each field also has multiple rules. I'm using CakePHP version 2.4.2.
The problem I have at the moment, after multiple permutations of updating and/or moving around the use 'last', 'allowEmpty', 'required', etc, is that the fields just aren't validating at all, or aren't executing all the rules when a field is populated.
Any advice on how to modify the code below to achieve the following behaviour is much appreciated:
1. One of the two fields must be populated;
2. The other rules attached to each field must validate as well (i.e. if a last name is passed, then it must be between 2 and 45 chars and alphanumeric only)
Here's the model code:
public $validate = array(
'last_name'=> array(
'needOne' => array (
'required' => FALSE,
'allowEmpty' => TRUE,
'last' => TRUE,
'rule' => array('checkOne','last_name'),
'message' => 'You must enter at least a contact name or email address.'
),
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'message' => 'Alphabets and numbers only'
),
'between' => array(
'rule' => array('between', 2, 45),
'message' => 'Between 2 to 45 characters'
)
),
'email' => array(
'needOne' => array (
'required' => FALSE,
'allowEmpty' => TRUE,
'last' => TRUE,
'rule' => array('checkOne','email'),
'message' => 'You must enter at least a contact name or email address.'
),
'emailAddress' => array (
'last' => TRUE,
'rule' => array('email', FALSE),
'message' => 'A valid Email address is required'
)
)
);
// Ensure at least the last name or email field value is provided
function checkOne($field) {
if(!empty($this->data[$this->User]['last_name']) ||
!empty($this->data[$this->User]['email'])){
return true;
} else {
return false;
}
}
Thanks in advance!
Thanks very much vicocamacho. I kept at it and, in addition to your advice, found the solution also lay in adding a 'required' => false in the view.
Here's the working solution for any one else with this problem:
The model:
public $validate = array(
'last_name'=> array(
'needOne' => array (
'rule' => 'checkOne',
'message' => 'You must enter at least a contact name or email address.'
),
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'message' => 'Alphabets and numbers only',
'allowEmpty' => TRUE
),
'between' => array(
'rule' => array('between', 2, 45),
'message' => 'Between 2 to 45 characters',
'allowEmpty' => TRUE
)
),
'email' => array(
'needOne' => array (
'rule' => 'checkOne',
'message' => 'You must enter at least a contact name or email address.'
),
'emailAddress' => array (
'rule' => 'email',
'message' => 'A valid Email address is required',
'allowEmpty' => TRUE
)
)
);
// Ensure at least the last name or email field value is provided
public function checkOne($data) {
if(!empty($this->data[$this->alias]['last_name'])
|| !empty($this->data[$this->alias]['email'])) {
return TRUE;
} else {
return FALSE;
}
}
The view/fields (I'm using Bootstrap):
echo $this->Form->input('last_name', array(
'required' => false,
'fieldset' => false,
'label' => false,
'before' => '<label class="control-label">Last Name <span class="one-required">*</span></label>',
'class' => 'form-control',
'placeholder' => 'Last Name',
'div' => 'form-group col-sm-12',
'error' => array(
'attributes' => array(
'wrap' => 'div',
'class' => 'alert alert-danger'
)
)
)
);
echo $this->Form->input('email', array(
'required' => false,
'fieldset' => false,
'label' => false,
'before' => '<label class="control-label">Email <span class="one-required">*</span></label>',
'after' => '',
'class' => 'form-control',
'div' => 'form-group col-sm-12 col-xs-12',
'error' => array(
'attributes' => array(
'wrap' => 'div',
'class' => 'alert alert-danger'
)
)
)
);
Thanks.
Write a custom rule that will check if one of both fields is not empty and use that rule on both fields. And set allowEmpty to true for the other rules.
You should allowEmpty in all the rules that do not check if the fields are present, i updated your code so you can see what i mean, also you need to change the $this->User index in your checkOne to $this->alias otherwise it will always return false:
public $validate = array(
'last_name'=> array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'message' => 'Alphabets and numbers only',
'allowEmpty' => true
),
'between' => array(
'rule' => array('between', 2, 45),
'message' => 'Between 2 to 45 characters',
'allowEmpty' => true
)
),
'email' => array(
'needOne' => array (
'rule' => 'checkOne',
'message' => 'You must enter at least a contact name or email address.'
),
'emailAddress' => array (
'allowEmpty' => true,
'rule' => 'email',
'message' => 'A valid Email address is required'
)
)
);
// Ensure at least the last name or email field value is provided
function checkOne($field) {
if(
!empty($this->data[$this->alias]['last_name']) ||
!empty($this->data[$this->alias]['email'])
)
{
return true;
} else {
return false;
}
}
Okay, so, in short, I'm trying to validate a form, as I've done a million times before with no trouble. However, I'm finding that on logging the validation errors, all the invalidated fields have an index in the validationErrors array but the messages are empty.
Yes, I've definitely set the validation messages in the model so I'm unsure why it's empty.
Here are my model validations:
public $validate = array(
'effective_policy_date' => array(
'date' => array(
'rule' => array('date'),
'message' => 'Invalid date format',
),
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Policy date required',
),
),
'business_address' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Business address required',
),
),
'city' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'City required',
),
),
'zip_code' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Zip code required',
),
),
'state_id' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'State required',
),
),
'contact_person' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Contact person required',
),
),
'phone' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Phone number required',
),
),
'email' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
'message' => 'Email address required',
),
'email' => array(
'rule' => array('email'),
'message' => 'Invalid email format',
),
),
);
Here's the output of the validationErrors array after submitting the form with empty fields:
[AccountsRequest] => Array
(
[effective_policy_date] => Array
(
)
[policy_number_one] => Array
(
)
[policy_number_two] => Array
(
)
[policy_number_three] => Array
(
)
[policy_number_four] => Array
(
)
[business_address] => Array
(
)
[city] => Array
(
)
[zip_code] => Array
(
)
[state_id] => Array
(
)
)
For completeness sake, here's my Form->create array I use in the view and the controller action responsible for handling the form submission:
Form create() method
<?php
echo $this->Form->create(
'Request',
array(
'novalidate' => 'novalidate',
'action' => 'new_request',
'inputDefaults' => array(
'label' => false,
'div' => false,
'error' => array(
'attributes' => array(
'wrap' => 'label', 'class' => 'error'
)
)
)
)
);
?>
Controller action
public function new_request()
{
$this->page_id = 'requester_newform';
if($this->request->is('post'))
{
if($this->Request->saveAll($this->request->data, array('deep' => true, 'validate' => 'only')))
{
$this->Session->setFlash('Request saved successfully', 'flash/success');
}
else
{
$this->Session->setFlash('Could not save request. Please correct validation errors', 'flash/error');
}
}
}
You'll see some indeces in the validation array that aren't in the validationErrors, that's simply because I haven't quite finished converting the raw HTML to CakePHP forms.
Problem: The validationErrors array shouldn't be empty. It should contain the messages for the notEmpty rules and as a result there are empty error validation elements on the Form's frontend. Any ideas about what I'm doing wrong?
Aarg, how annoying. I've figured it out and it's a lesson well learnt.
For anyone having a similar issue in the future, make sure that your input fields conform to the relationships of the current form's Model.
For instance, in this example, my form's model is 'Request'. Request hasMany 'AccountsRequest'. So my form inputs were something like:
AccountsRequest.effective_policy_date
where it should have been
AccountsRequest.0.effective_policy_date
With this change, my model validation messages are now showing without issue.
I'd still love to know, however, why CakePHP even picked up those fields as invalid and further, if it was intelligent enough to pick up those fields as invalid why it didn't give me validation messages.
Oh well.....
i'm new to phpunit and have read the documentation on mock objects but it isn't very clear.
I am trying to write a simple test that asserts a method within a class is called. With the following code, i am testing that when the Client::exchangeArray is called, a call is made to Client::getInputFilter.
class Client implements InputFilterAwareInterface
{
public function getInputFilter() {
if(!$this->_inputFilter){
$inputFactory = new InputFactory();
$inputFilter = new InputFilter();
$inputFilter->add($inputFactory->createInput(array(
'name' => 'id',
'required' => true,
'filters' => array(
array(
'name' => 'Int'
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'name',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
),
array(
'name' => 'StripNewLines'
),
array(
'name' => 'Alpha'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 100
)
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'surname',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 100
)
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'email',
'required' => false,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 150
)
),
array(
'name' => 'EmailAddress'
)
)
)));
$this->_inputFilter = $inputFilter;
}
return $this->_inputFilter;
}
public function exchangeArray($data){
$inputFilter = $this->getInputFilter();
$inputFilter->setData($data);
if(!$inputFilter->isValid()){
throw new \Exception('Invalid client data');
}
$cleanValues = $inputFilter->getValues();
$this->_id = (isset($cleanValues['id']) ? $cleanValues['id'] : null);
$this->_name = (isset($cleanValues['name']) ? $cleanValues['name'] : null);
$this->_surname = (isset($cleanValues['surname']) ? $cleanValues['surname'] : null);
$this->_email = (isset($cleanValues['email']) ? $cleanValues['email'] : null);
}
}
Here is my test case:
public function testExchangeArrayCallsInputFilter(){
$data = array('id' => 54,
'name' => 'john',
'surname' => 'doe',
'email' => 'john.doe#domain.com'
);
$mock = $this->getMock('Client', array('exchangeArray'));
$mock->expects($this->once())
->method('getInputFilter');
$mock->exchangeArray($data);
}
...and i'm getting the following error:
Expectation failed for method name is equal to
when invoked 1 time(s). Method was expected to be called 1 times,
actually called 0 times.
Where am i going wrong?
It all depends on what you want test and what you want mock. Basing on the name of your test I assume that you want test exchangeArray method.
The getMock method takes as second argument names of methods that you want mock. It means that they will never be called.
So, if you want to test exchangeArray method and mock getInputFilter you should pass "getInputFilter" in second argument, like below:
$mock = $this->getMock('Client', array('getInputFilter'));
$mock->expects($this->once())
->method('getInputFilter');
$mock->exchangeArray($data);
But be careful. You didn't tell your mock to return anything, so it will return null value. That means that you'll get a fatal error on the second line of exchangeArray method (trying to call a method on a non-object). You should prepare some faked filter object to deal with that, eg:
// $preparedFilterObject = ...
$mock = $this->getMock('Client', array('getInputFilter'));
$mock->expects($this->once())
->method('getInputFilter')
->will($this->returnValue($preparedFilterObject);
$mock->exchangeArray($data);
And if you want to invoke the "real" getInputFilter method - then you just can't mock this method.
I have a problem with my module views integration. I need to provide information about user who added video and timestamp. Video field is a CCK Embedded Media Field and it stores in content_field_3d_party_video table.
The schema is defined from the following code.
function MODULE_schema() {
$schema = array();
$schema['video_data'] = array(
'description' => t('Users and timestamps for video field'),
'fields' => array(
'value' => array(
'description' => t('Emfield value'),
'type' => 'varchar',
'length' => '255',
'not null' => TRUE,
'default' => '',
),
'uid' => array(
'description' => t('User id'),
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'timestamp' => array(
'description' => t('Timestamp'),
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array('value'),
'indexes' => array(
'timestamp' => array('timestamp'),
'uid' => array('uid'),
),
);
return $schema;
}
The hook_views_data() implementation is the following.
function MODULE_views_data() {
$data = array();
$data['video_data']['table']['group'] = t('Video Data');
$data['video_data']['table']['join'] = array(
'node' => array(
'left_table' => 'content_field_3d_party_video',
'left_field' => 'field_3d_party_video_value',
'field' => 'value',
),
'users' => array(
'left_field' => 'uid',
'field' => 'uid',
),
);
$data['video_data']['value'] = array(
'title' => t('Video value'),
'relationship' => array(
'base' => 'content_field_3d_party_video',
'base field' => 'field_3d_party_video_value',
'field' => 'value',
'handler' => 'views_handler_relationship',
'label' => t('Video value'),
),
);
$data['video_data']['uid'] = array(
'title' => t('User id'),
'relationship' => array(
'base' => 'users',
'base field' => 'uid',
'field' => 'uid',
'handler' => 'views_handler_relationship',
'label' => t('User id'),
),
);
$data['video_data']['timestamp'] = array(
'title' => t('Timestamp field'),
'field' => array(
'handler' => 'views_handler_field_date',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort_date',
),
'filter' => array(
'handler' => 'views_handler_filter_date',
),
);
return $data;
}
The table isn't included in the SQL query generated for the view.
SELECT node.nid AS nid,
node.title AS node_title,
node.language AS node_language,
node_data_field_3d_party_video.field_3d_party_video_embed AS node_data_field_3d_party_video_field_3d_party_video_embed,
node_data_field_3d_party_video.field_3d_party_video_value AS node_data_field_3d_party_video_field_3d_party_video_value,
...
node.type AS node_type,
node.vid AS node_vid
FROM node node
LEFT JOIN content_field_3d_party_video content_field_3d_party_video_video_data ON value = content_field_3d_party_video_video_data.field_3d_party_video_value
LEFT JOIN users users_video_data ON uid = users_video_data.uid
LEFT JOIN content_field_3d_party_video node_data_field_3d_party_video ON node.vid = node_data_field_3d_party_video.vid
WHERE ...
May you help me?
This is the solution the OP previously posted in the question.
To correctly join the table used for a CCK field, we must specify node_data_field_3d_party_video as left_table, instead of content_field_3d_party_video.
$data['video_data']['table']['join'] = array(
'node' => array(
'left_table' => 'node_data_field_3d_party_video',
'left_field' => 'field_3d_party_video_value',
'field' => 'value',
),
'users' => array(
'left table' => 'users',
'left_field' => 'uid',
'field' => 'uid',
),
);