Validating length depending on a setting in CakePHP - validation

Note that I am using CakePHP 1.3.
I would like to validate the length of several fields of a model depending on a limit defined by the administrator in the database.
I have one model called Setting through which I can fetch the maxLength values. My idea is to use the beforeValidate method to fetch them, and then set the $validate parameter accordingly :
<?php
class Mod extends AppModel
{
var $belongsTo = array('IBelong');
var $hasMany = array('IHaz');
function beforeValidate() {
// Fetch the maxLength settings : requestAction to the SettingsController ?
// Somehow do $this->Setting->find... ?
// Then set the $validate attribute
}
}
?>
What method can I use to get the maxLength values in the beforeValidate callback ?
Thanks !
Edit : following comments by Dave, here is what I am currently doing (and it works) :
<?php
class Mod extends AppModel
{
var $belongsTo = array('IBelong');
var $hasMany = array('IHaz');
function beforeValidate() {
App::import('Model', 'Setting');
$setting = new Setting();
// Use $setting->find... to fetch the settings
// Set the $validate attribute to validate using the settings
}
}
?>
However, I am still not sure if this is the right approach.
Note that I have several attributes to validate, and I would like to avoid having to call $setting->find several times for best performance.

Data Validation is very thoroughly explained in the CakePHP book.
If you read the Custom Validation Rules area, you'll see an example of them pulling data from the database to use in their validation - exactly like what you want.
(Here's Custom Validation Rules for 1.3)

Related

Laravel request validation by groups

So, I have a Creators table with all informations related to the creator.
This table has some nullable columns that can be filled depending on what type of creator you are.
As an example one can be an "indipendent" creator or a "company" creator. In the second case the creator will have to fill in the columns related to his company.
At the moment I am arranging it with something like this inside the Controller:
public function isValid(Request $request)
{
$creator = //creator validation rules;
$company = //company validation rules;
$transfer = //another set of rules;
if (!$request->indipendent)
$creator = array_merge($creator, $company);
$creator = array_merge($creator, $transfer);
return $request->validate($creator);
}
I want to however create a new CreatorRequest that validates the request.
The only method I could think of was to override the validate() function, but is there a way to do this by only utilizing the rules() function?
Ideally I would like to have the $creator $company and $transfer inside the rules and be able to choose which groups I want validated.
For example:
$request->validate(['creator', 'company']); //doesn't validate transfer
What is the best approach?
I say the best approach here is to break your request out into three separate request classes, and inject them using the laravel container:
public function isValid(CreateCreatorRequest $creator, CreateCompanyRequest $company, TransferRequest $transfer)
{
if (!$request->indipendent)
$creator = array_merge($creator, $company);
$creator = array_merge($creator, $transfer);
return $request->validate($creator);
}
Laravel will automatically handle passing the current request into those request classes, and you'll get your validated data as an array. The handy advantage here is you can force an interface directly against an intended action - you can apply the same CreateCompanyRequest in a different controller action and have a central place for all the validation rules.
https://laravel.com/docs/9.x/validation#creating-form-requests

Backpack V4 modifying field before store

In 3.6 version of backpack I can change an attribute value before storing it.
I have this code
If ($request->description == "") {
$request->description="User has not entered any description";
}
$redirect_location = parent::storeCrud($request);
What can I do to get the same in V4? I'm reading this guide but I can't make it to work.
This is what I'm trying in V4
public function store(PedidoRequest $request)
{
Log::debug('testing...');
If ($request->description == "") {
$request->description="User has not entered any description";
}
$redirect_location = $this->traitStore();
return $redirect_location;
}
The Request object in Laravel, Illuminate\Http\Request, doesn't have the ability to set the inputs via the properties like that, no __set method ($request->description = '...' does not set an input named description). You would have to merge the inputs into the request or use the array syntax to do that:
$request->merge(['description' => '...']);
// or
$request['description'] = '...';
But since backpack seems to have abstracted things apparently you aren't controlling anything in your controller methods you could try this:
$this->crud->request->request->add(['description'=> '...']);
Potentially:
$this->request->merge(['description' => '...']);
That would be assuming some trait the Controller uses is using the Fields trait.

Yii2 : How to validate XSS (Cross Site Scripting) in form / model input?

Yii2 has support for XSS(cross-site-scripting ) validation of displayed data using the helper class\yii\helpers\HtmlPurifier, however this only validates and cleans up output code like this
echo HtmlPurifier::process($html);
How to validate input for XSS of input such that this data is not stored in the database itself ?
This can be done using a filterValidator by calling the process as named callable function of validation like this
class MytableModel extends ActiveRecord {
....
public function rules(){
$rules = [
[['field1','field2'],'filter','filter'=>'\yii\helpers\HtmlPurifier::process']
];
return array_merge(parent::rules(),$rules);
}
....
}
Where field1, field2 etc are the inputs fields to be validated, the same applies for Form Model validations as well
in the before validate method add the following:
public function beforeValidate()
{
foreach (array_keys($this->getAttributes()) as $attr){
if(!empty($this->$attr)){
$this->$attr = \yii\helpers\HtmlPurifier::process($this->$attr);
}
}
return parent::beforeValidate();// to keep parent validator available
}
it will help you if you want to run Xss Validator before validate/save all attributes nested of adding the following line
return array_merge(parent::rules(),$rules);
to every class extends the new active record

CakePHP validation not working for contact form

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.

Need help figuring out how to write my zend view helper

I'm fairly new to Zend Framework and MVC in general so I'm looking for some advice. We have a base controller class in which we have some methods to obtain some user information, account configurations, etc.
So I'm using some of those methods to write out code in various controllers actions, but now I want to avoid duplicating this code and further more I would like to take this code outside of the controller and in a view helper as it is mainly to output some JavaScript. So the code in the controller would look like this:
$obj= new SomeModel ( $this->_getModelConfig () );
$states = $obj->fetchByUser ( $this->user->getId() );
//Fair amount of logic here using this result to prepare some javascript that should be sent to the view...
The $this->_getModelConfig and $this->user->getId() are things that I could do in the controller, now my question is what is the best way to pass that information to the view helper once i move this code out of the controller ?
Should I just call these methods in the controller and store the results into the view and have the helper pick it up from there ?
Another option I was thinking of was to add some parameters to the helper and if the parameters are passed then I store them in properties of the helper and return, and when called without passing the parameters it performs the work. So it would look like this:
From controller:
$this->view->myHelper($this->user->getId(), $this->_getModelConfig());
From view:
<?= $this->myHelper(); %>
Helper:
class Zend_View_Helper_MyHelper extends Zend_View_Helper_Abstract
{
public $userId = '';
public $config = null;
public function myHelper ($userId = null, $config = null)
{
if ($userId) {
$this->userId = $userId;
$this->config = $config;
} else {
//do the work
$obj = new SomeModel($this->config);
$states = $obj->fetchByUser($this->userId);
//do the work here
}
return $this;
}
}
Any advice is welcomed!
Firstly the ASP style ending tag here at "$this->myHelper(); %>" is bad practice, with that said it is more advisable to keep the logic in the model and the controller just being used to call the model, get the results and spit that to the view for viewing.
what I would do is, if i simply want to pass a bunch of values to the view, i stuff them in an associative array and send them over.
anyway you should not be doing your ...
"//Fair amount of logic here using this result to prepare some javascript that should be sent to the view..."
part in the controller, I would advice you to make a new model that does that logic stuff for you, and you just call your model in the controller pass it what ever arguments that are needed and then spit the result of that to the view.
The best way is to get the data from your model throught your controller, and then pass to the view. But if you really need a custom helper to echo the view parts, we only will know if you say exactly what you're trying to do.
If you already have this logic in a helper, try to just pass the parameters in your view myhelper($this->params); ?>
You may want take a look at this approach too:
// In your view to put javascript in the header
// You can loop trought your data and then use it to generate the javascript.
<?php $this->headScript()->captureStart(); ?>
$().ready(function(){
$('#slideshow').cycle({
fx: 'fade',
speed: 1000,
timeout: 6500,
pager: '#nav'
});
});
<?php $this->headScript()->captureEnd() ?>

Resources