I'm using 2.4.7 and I want to include some validation for two fields which take in prices (e.g. €1 or 2 for €3). Originally I thought that perhaps I would need to resort to validating user input but as the answer suggests it was a database issue.
The encoding within SilverStripe was defaulting to ASCII which converted the symbols such as the euro symbol. In the end I need to add
$this->response->addHeader("Content-Type", "application/json; charset='utf-8'");
to the init method in the controller. This corrected the encoding issue and prevented a hacky workaround taking place. Many thanks for the insight on this one.
Thanks
I'm assuming you want to do this in the CMS. If that's the case, the easiest way is probably to create a new class which extends the TextField class and adds a public function validate() method which performs your validation (see the CreditCardField class for an example).
class FancyCurrencyField extends TextField {
public function validate($validator) {
// Do your validation
if ($invalid) {
$validator->validationError(
$this->name,
"Please don't use currency symbols.",
"validation",
false
);
return false;
}
return true;
}
}
Once you've created your class, you can modify the form fields in your getCMSFields() function on the DataObject and use the new class in place of TextField.
Having said that, it feels like output encoding and not input validation is the root cause of your problem. I'd check to make sure that everything is setup to use UTF-8.
I encountered a problem with the PHP function substr. I just used mb_substr instead and it solved my issue.
Please view http://www.silverstripe.org/general-questions/show/11797#post369831
Related
I'm building a pretty complex and dynamic form via the Lithium PHP framework.
I've got the form working and saving to MongoDB with little problem. But I am having trouble with validation.
Simple validations (such as checking if a field is not empty or is numeric) are working fine. But I have to do a few complex validations that rely on a number of fields in the form.
For example, I have a form where a user can enter a question and then enter an unlimited number of possible answers for this question. The field ID for each answer is listed such as "answer_1", "answer_2", "answer_3", etc. The user can add an unlimited number of answers. This happens via some fancy JavaScript that inserts extra elements to the form on the client side.
At the validation level, I want to make sure that every answer which was added is not null.
I would like to do this using the "traditional" Validator functionality built within Lithium. I am also doing this at the Model level, not the Controller level (note - I have a workaround to solve this on the Controller level, but would rather do it the "right" way at the Model)
The problem, as far as I can tell, is that you can only pass a single value to the validator rule. I just need to pass back ALL values in the form to the validator. If I could do that, I would be golden. The pseudo-code for what I'm looking to do looks like this:
Validator::add('CorrectTest', function(&$value, $format = null, array $options = array()) {
foreach ($_data as $key => $value) {
if (stristr($key, "answer_")) {
if ($value == "") {
return false;
}
}
}
return true;
});
This code doesn't work, because the $_data value is not present. If I could just figure out a way to get a fully-populated "$_data" object into the Validator function, I think I could get this to work.
Thanks in advance for the help
Take a look at what's inside $options. You should have a 'values' key in there that has all of the values from the form.
So try
$_data = $options['values'];
I am trying to do some very simple validation in my CakePHP contact form, but validation does not work eventhough I think I did everything necessary. Here's what I did:
I made a model like this:
class Office extends AppModel
{
var $name = 'Office';
var $useTable = false;
public $validate = array('onderwerp' => 'notEmpty');
}
(I also tried many other values for $validate from the CakePHP online manual)
In Config/bootstrap.php I made this rule for not letting CakePHP expect plural "Offices":
Inflector::rules('plural', array('rules' => array(),
'irregular' => array(),
'uninflected' => array('office')));
In OfficeController, I do this in my method contact():
$this->Office->set($this->request->data);
if($this->Office->validates()){
echo "code validates";
} else {
print_r($this->Office->validationErrors);
}
And in my Office/contact.ctp view, I have (amongst other code like starting and ending the form) this code:
$this->Form->input('onderwerp', array('label'=>false, 'size' => 60));
Now, even when I fill in the form, leaving empty the field 'onderwerp', it executes the code that should be executed when the code is executed.
When I print_r($this->request->data) or print_r($this->Office) I see that my onderwerp field is there and that it is empty (or filled when I do fill in something).
Now, when I add a public function validates() in my model and echo something there, it IS being displayed. So I'd say CakePHP knows where to find my model, and does execute my controller code. I also tried adding return parent::validates(); in my validates() function, but this also yielded no validation error, or any other error for that matter. My debug level is set to 2.
I guess I'm missing a needle in this haystack. Thanks for helping me finding it!
so drop all the inflector stuff.
and use the right model in your Form->create()
either
$this->Form->create(null)
or
$this->Form->create('Office');
and if you follow my advice to use a table less model with schema you will also have more power over input creation and validation.
the scenario is i have a form in my Yii project that will take the username as input and sends the user a mail containing activation link if he has not received one. the form name is ResendActivationLinkForm which extends the CFormModel class. now at the submission time i wanna check if the username exists or not in the database using AJAX...How to use yii's own classes and functions to accomplish that?
well thanks for replies..but i got it in a simpler fashion.
i just added an array inside the form model ResendActivationLinkForm depicting my rule.. eg..
public function run(){
return array(
.....
.....
array('username','exist','className'=>'User'),
);
}
where username is my attributeName, exist is the validator alias and className is the Model class name whose attribute it should look for...
you can look at http://www.yiiframework.com/wiki/56/ for more details. :) Happy Coding. :)
If Usermodel is the model that has a username attribute, you can do something like this.
if(Usermodel::model()->findByAttributes(
array(),
'username = :inputtedUsername',
array(':inputtedUsername' => $_POST['username'],)))
{
//user found
}else{
//user not found
}
For more information about the various CActiveRecord methods check the website
I'd extend the form model with a custom validator, such as array('username','UsernameExistsValidator'). This validator class should extend CValidator and implement public function validateAttribute($object,$attribute) which can use $this->addError() to flag if the username is not available. See the source for other Yii validators if you need some more input on the bits in there.
The logic from the answer above would fit into validateAttribute,
I'm developing a view that need to reuse a model, I'm following this documentation http://docs.joomla.org/Using_multiple_models_in_an_MVC_component. But that reference do the trick just (at least as far as I understand) when I use the parameter get task. if I use the view, joomla get me null data.
more clearly
controller.php - the task I named as the view I need
function viewdowhatIneed(){
$view = & $this->getView('viewdowhatIneed',html);
$view->setModel( $this->getModel( 'thenotdefaultmodelthatIneed' ), true );
$view->display();
}
model - thenotdefaultmodelthatIneed.php
class BLAModelthenotdefaultmodelthatIneed extends Jmodel{
function getReusableData0(){...}
function getReusableData1(){...}
}
view - view.html.php
class BLAViewviewdowhatIneed extends JView{
function display($tpl=null){
$dataneedit0 = $this->get('ReusableData0');
$dataneedit1 = $this->get('ReusableData1');
$this->assignRef('dataneedit0',$dataneedit0);
$this->assignRef('dataneedit1',$dataneedit1);
parent::display($tpl);
}
}
SO, what happen to me is:
example.com/index.php?option=com_BLA&view=viewdowhatIneed -> variables(datadataneedit0,dataneedit1) == NULL
example.com/index.php?option=com_BLA&task=viewdowhatIneed -> variables(datadataneedit0,dataneedit1) == Get me right data
then, my question is, is there a way to do the same thing, by using view parameter without task parameter (btw, I know this could be not a important problem, but I'm not an expert and on this reference http://docs.joomla.org/How_Joomla_pieces_work_together, it says:
The task part may or may not exist. Remember that if you omit it you are defaulting to task=display
so I really want to know that. In other words, can my view force to check the controller or vice versa.
Thanks in advance, excuse my english
I have a wrapper class that is meant to get and set code from a property in one of my dbml's partial classes. The reason for the wrapper is for a specialized get, which pre-formats the value. Here's what the wrapper looks like (NOTE: this is not the actual code, but represents everything but the formatting accurately):
partial class Class1
{
public string PropertyFormatted
{
get
{
var ret = Property.Substring(1);
return ret;
}
set { Property = value; }
}
}
This wrapper is bound using Bind() in a formview for the edit page. For some reason, the wrapper's value is set twice on update and the second time through the value is re-assigned its original value (causing the property to remain, ultimately, unchanged). However, when the wrapper is replaced with the property itself, there is no problem with saving to the database.
Any ideas what may be the cause of this?
The dbContext should be automatically detecting changes via this method:
http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbchangetracker.detectchanges(v=vs.103).aspx
You may have inadvertently disable auto detect changes or something of the like. Try manually calling the method and see if that makes a difference.
Good luck!