I have these code in index action of controller:
public function actionIndex()
{
$cid = #$_GET['cid'];
$country = Country::model()->findByPk($cid);
if($cid)
$dataProvider=new CActiveDataProvider('City', array(
'criteria'=>array(
'condition'=>'ci_co_id ='.$cid,
),
));
else
$dataProvider=new CActiveDataProvider('City');
$this->render('index',array(
'dataProvider'=>$dataProvider,
'country' => $country
));
}
and these in view/index.php file:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'city-grid',
'dataProvider'=>$dataProvider,
'filter' => $dataProvider,
'columns'=>array(
array(
'name' => ' ',
'value' => '$row + 1',
),
'ci_name',
'ci_pcode',
array(
'class'=>'CButtonColumn',
),
)
));
?>
but Yii gives me this error:
CActiveDataProvider and its behaviors do not have a method or closure named "getValidators".
What is the problem?
The filter has to be a class that extends CModel. However, you don't seem to be doing any actual filtering, so you can just comment the filter line of your CGridView out.
As a side note, you have major security hole in your criteria. You are leaving yourself wide open to an SQL injection attack.
Specify your criteria as follows to let the database handler properly escape the input:
'criteria'=>array(
'condition'=>'ci_co_id =:cid',
'params'=>array(':cid'=>$cid),
),
Related
I wonder what I've made wrong, I want to save in db some values whats not come form POST or GET:
public function saveAction()
{
$wikiTable = $this->getServiceLocator()->get('WikiTable');
$data = array('source' => $someVal);
$form = new WikiForm();
$inputFilter = new \MyApp\Form\WikiFilter();
$form->setInputFilter($inputFilter);
$form->setData($data);
$this->saveWiki($form->getData());
//$this->saveWiki($data);
}
WikiFilter:
$this->add(
array(
'name' => 'source',
'required' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
)
)
);
And Form:
$this->add(array(
'name' => 'source',
'type' => 'Zend\Form\Element\Hidden',
'options' => array(
'label' => 'source',
)
));
In response I recive error:
Zend\Form\Form::getData cannot return data as validation has not yet
occurred
After this line:
$form->setData($data);
You need to put the rest of your code into something like this:
if($form->isValid()){
$this->saveWiki($form->getData());
}
Otherwise your form isn't validated and you won't get any data back from it by calling $form->getData()
So whenever you work with a form (not matter if the data come from a POST request or not) make sure to call the function isValid() on the form variable because otherwise you won't get the data back and you will get the error you wrote before
I have this model in a project, built with Lithium PHP framework:
<?php
namespace app\models;
class Prices extends Base {
protected $_schema = array(
'_id' => 'id',
.......
'price' => array('float', 'default' => 0)
);
public $validate = array(
.......
'price' => array(
array('notEmpty', 'message' => 'Price cannot be empty.'),
array('numeric', 'message' => 'Price must be number.')
)
);
}
?>
The problem is that the model treats zero as invalid price too.
I tried with adding additional properties - allowEmptyValue - with no result.
I tried with custom validation rule - it gets ignored. (???)
I tried to remove the float from the $_schema and then it accepts zeros ... but then it also accepts text for price. (?!?!?!)
Do you have any idea what is the problem?
You can use the custom validation. For example:
Validator::add('price', function($value, $rule, $option){
if(floatval($value) == 0){
return false;
}
//you can add more rules here
return true;
});
and add "price" to the list of rules
'price' => array(
array('notEmpty', 'message' => 'Price cannot be empty.'),
array('numeric', 'message' => 'Price must be number.'),
array('price', 'message' => 'Please enter a valid price.')
)
I'm not getting it!.. Can please someone explain, how to translate form labels? A simple example would be great.
Thank you in advance!
class Search\Form\CourseSearchForm
...
class CourseSearchForm extends Form {
...
public function __construct(array $cities) {
parent::__construct('courseSearch');
...
$this->add(array(
'name' => 'city',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Stadt',
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
));
...
}
}
view script /module/Search/view/search/search/search-form.phtml
<?php echo $this->form()->openTag($form); ?>
<dl>
...
<dt><label><?php echo $form->get('city')->getLabel(); ?></label></dt>
<dd><?php echo $this->formRow($form->get('city'), null, false, false); ?></dd>
...
</dl>
<?php echo $this->form()->closeTag(); ?>
<!-- The formRow(...) is my MyNamespace\Form\View\Helper (extends Zend\Form\View\Helper\FormRow); the fourth argument of it disables the label. -->
The module/Application/config/module.config.php is configured:
return array(
'router' => ...
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => ...
'view_manager' => ...
);
I also edited my view and use the FormLabel view helper:
<dt><label><?php echo $this->formLabel($form->get('city')); ?></label></dt>
Furthermore I debugged the FormLabel at the place, where the tranlator is used (lines 116-120) -- seems to be OK.
But it's still not working.
EDIT
The (test) items for labels, I added to the de_DE.po file manually, are tranlated. The ZF2 side problem was actually, that I was using $form->get('city')->getLabel() instead of $this->formlabel($form->get('city')) in th view script.
The problem is now, that the labels are not added to the de_DE.po file. But it's not a ZF2 issue anymore, so I've accept Ruben's answer and open a new Poedit question.
Instead of using:
<?php echo $form->get('city')->getLabel(); ?>
You should use the formlabel view helper. This helper automatically uses your translator during rendering if you have inserted it in your ServiceManager. Most likely you will have it in your Application's module module.config.php:
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
Once you do use the formlabel view helper:
echo $this->formLabel($form->get('city'));
And of course make sure your translations are in your .po file.
i think your problem is that you label are not detected by poedit (or similar tool), so you have to add them manually to your poedit catalogs (.po)
to make your label strings detected by tools like poedit, your strings need to be used inside a translate() function or _() (other function can be added in Catalog/properties/sources keyword)
as the _() function is not user in ZF2 (today) so a tiny hack is to add a function like this in your index.php (no need to modify anything, this way, in poedit params):
// in index.php
function _($str)
{
return $str;
}
and in your code, just use it when your strings are outside of a translate function
//...
$this->add(array(
'name' => 'city',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => _('myLabel') , // <------ will be detected by poedit
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
));
//...
or like this if you prefer
$myLabel = _('any label string'); // <--- added to poedit catalog
//...
'options' => array(
'label' => $myLabel ,
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
#Ruben says right!
Me I use PoEdit to generate my *.mo files and to be sure to get all translations in the file, I create somewhere (in view for example) a file named _lan.phtml with all text to be translated :
<?php echo $this->translate("My label");
... ?>
Of course, Poedit has to be configured to find my keywords. check this to how to configure it
All solutions don't use the power of ZF2. You must configure your poedit correctly :
All things are here :
http://circlical.com/blog/2013/11/5/localizing-your-twig-using-zend-framework-2-applications
Its possibile save multiple translations of the same field in a single form?
I have a model with Behavior Translate to translate the name field. The three translations (deu, eng, ita) are properly recorded in the i18n table but the field is not properly validated! Any suggestions?
app/Model/Category.php
class Category extends AppModel {
public $actsAs = array('Translate' => array('name' => 'TranslateName'));
public $validate = array(
'name' => array(
'notempty' => array(
'rule' => array('notempty'),
'message' => 'Error notempty',
),
),
);
...
app/View/Categories/admin_edit.ctp
<?php
echo $this->Form->create('Category');
echo $this->Form->input('Category.id');
echo $this->Form->input('Category.name.deu', array('label' => __d('Category', 'Name Deu')));
echo $this->Form->input('Category.name.eng', array('label' => __d('Category', 'Name Eng')));
echo $this->Form->input('Category.name.ita', array('label' => __d('Category', 'Name Ita')));
echo $this->Form->end(__d('app', 'Submit'));
?>
app/View/Controller/CategoriesController.php
if ($this->Category->save($this->request->data)) {
$this->Session->setFlash(__d('Category', 'The category has been saved'));
} else {
$this->Session->setFlash(__d('Category', 'The category could not be saved. Please, try again.'));
}
I have a similar Problem
But you can try out this - it should solve it for you: https://github.com/zoghal/cakephp-MultiTranslateBehavior
I am trying to have a Checkbox "Agree TOS".
If the Checkbox is not checked, I want to put out a Flash Message.
How do I do this?
My View:
<?php
echo $form->create('Item', array('url' => array_merge(array('action' => 'find'), $this->params['pass'])));
echo $form->input('Search', array('div' => false));
echo $form->submit(__('Search', true), array('div' => false));
echo $form->checkbox('tos', array('label' => false, 'value'=>1)).' Agree TOS';
echo $form->error('tos');
echo $form->end();
?>
My Model:
var $check = array(
'tos' => array(
'rule' => array('comparison', 'equal to', 1),
'required' => true,
'allowEmpty' => false,
'on' => 'index',
'message' => 'You have to agree TOS'
));
This seems working for me. Hope it will help.
In model:
'tos' => array(
'notEmpty' => array(
'rule' => array('comparison', '!=', 0),
'required' => true,
'message' => 'Please check this box if you want to proceed.'
)
In view:
<?php echo $this->Form->input('tos', array('type'=>'checkbox', 'label'=>__('I confirm I have read the privacy statement.', true), 'hiddenField' => false, 'value' => '0')); ?>
Model
'agreed' => array(
'notempty' => array(
'rule' => array('comparison', '!=', 0),//'checkAgree',
'message' => ''You have to agree TOS'',
'allowEmpty' => false,
'required' => true,
'last' => true, // Stop validation after this rule
'on' => 'signup', // Limit validation to 'create' or 'update' operations
),
),
View
<?php echo $this->Form->input('agreed',array('value'=>'0'),array('type'=>'checkbox', 'label'=>'Agree to TOS')); ?>
basically, you add the rule "notEmpty" for this field to the public $validate array of the model.
this way an error will get triggered on Model->validates() if the checkbox has not been checked.
maybe some overhead in your case, but if you happen to use it more often try a DRY (dont repeat yourself) approach. you can also use a behavior for this to use this clean and without tempering too much with the model/controller:
// view form
echo $this->Form->input('confirmation', array('type'=>'checkbox', 'label'=>__('Yes, I actually read it', true)));
and in the controller action
// if posted
$this->Model->Behaviors->attach(array('Tools.Confirmable'=>array('field'=>'confirmation', 'message'=>'My custom message')));
$this->Model->set($this->data);
if ($this->Model->validates()) {
// OK
} else {
// Error flash message here
}
1.x:
https://github.com/dereuromark/tools/blob/1.3/models/behaviors/confirmable.php
for 2.x:
https://github.com/dereuromark/cakephp-tools/blob/2.x/Model/Behavior/ConfirmableBehavior.php
3.x: https://github.com/dereuromark/cakephp-tools/blob/master/src/Model/Behavior/ConfirmableBehavior.php
details:
http://www.dereuromark.de/2011/07/05/introducing-two-cakephp-behaviors/
I believe you need try save it into your model to catch your tos rules. I should do something like =
if(!$mymodel->save()){
// catch error tos.
}
$this->ModelName->invalidFields() returns an array of fields that failed validation.
You could try and search this for the tos field, and output a message if the key exists.
~untested (I'm not sure off the top of my head the exact structure of the invalidFields return array.
$failed_fields = $this->ModelName->invalidFields();
if(array_key_exists('tos', $failed_fields)) {
$this->Session->setFlash('Please accept the terms and conditions');
}
you don't even have to have validation rule for tos, just check that at the controller before saving the data.
if($this->data['Model']['tos']==1){
// save data
}else{
//set flash
}