Using system date in Laravel input validation - php

I am trying to create a few validation rules for an input form using Laravel 4.x and I have also go the Validator service from Laracasts.
Is there any way to use the current year, taken from the system date, and use that in the rules?
For example, I want to create a rule that says that the year entered in the input form does not exceed the current year (i.e : I cannot put in 2015 or any higher year as of this day)

You could do this:
'date' => array('min:'.date('Y'), 'max:'.date('Y'), 'date_format:"Y"');
Something along that line.. Catch my drift though right?
Note: This is untested.
PS: If for arguments sake you have a different format than just the year, you could split the inputs just for the validation.
$input = Input::only('date');
$input['date-year'] = date('Y', strtotime($input['date']));
//And then the validation rule will look something like this...
$rules['date-year'] = array('min:'.date('Y'), 'max:'.date('Y'), 'date_format:"Y"');
Hope that helped.

You can create new validation rule like this:
// Less than equal
Validator::extend('lte', function($attribute, $value, $parameters)
{
if ( (float) $value <= (float) $parameters[0] )
return true;
});
Use the new rule
$input = array('year' => 2015);
$rules = array('year' => 'lte:'.date('Y'));
$validation = Validator::make($input, $rules);

Related

Laravel 5.3 Validation: Unique period time which is set by two column (start_date, end_date)

Is there any way to validate the unique period times which is set by two column (start_date, end_date)? Please let me know if this is possible by using Laravel 5.3 validator.
Thanks
Arvi
So far as I know there is no way to accomplish such complex custom rules on Laravel. I understand that you really wanna do some thing like this:
//////////////////////////////////////////////////
// This is not working code. just an idea !!!
//
$data['period'] = $data['start_date'] . "-" . $data['end_date'];
$validator = Validator::make($data, [
'period' => Rule::unique('projects', DB::raw('concat(start_date, "-", end_date)')),
], [
'period' => 'Period is duplicated.',
]);
But Larvel does not accept this kind of rule (actually I am wondering why they do not accept this kind of approach)
So you have 2 options.
Solution 1. Create a view in the database, which will have additional column "period" which is made by concat(start_date,"-",end_date).
And then make the code like following.
$data['period'] = $data['start_date'] . "-" . $data['end_date'];
$validator = Validator::make($data, [
'period' => Rule::unique('projects', DB::raw('concat(start_date, "-", end_date)')),
], [
'period' => 'Period is duplicated.',
]);
if ($validator->fails()) {
// do some thing
} else {
unset($data['period']); // When adding or update, 'period' will cause error because period is only in view, not in table itself
// do insert or update
}
Solution 2. Just pass normal validation except for the unique checking, after all validation done, you do checking yourself by searching in the table manually.
Like following:
if (Project::where(DB::raw("concat(start_date, '-', end_date)"), "=", $data['start_date'] . "-" . $data['end_date'])->count() > 0) {
// now this is not unique, so do something
}

Trouble with date and time formats saving in my database

I have trouble saving my date and time values. I tried different formats, here the actual try.
validator in my form:
$datum=$this->CreateElement('text','datum')
->setAttrib('size', '10')
->addValidator(New Zend_Validate_Date('MM-DD-YYYY'));
$zeit=$this->CreateElement('text','zeit')
->setAttrib('size', '10')
->addValidator(new Zend_Validate_Date(array('format' => 'H:i:s')));
Snippet of my Controller addAction
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$logenr = $this->_getParam('kopfnr', 0);
$kopfnr = $logenr;
$dat= $form->getValue('datum');
$zeit = $form->getValue('zeit');
$thema = $form->getValue('thema');
$aktermine = new Application_Model_DbTable_Aktermine();
$aktermine->addTermine( $kopfnr, $dat, $zeit, $thema);
And, my add function in my database class:
public function addTermine($kopfnr, $datum, $zeit, $thema)
{
$data = array(
'kopfnr' => $kopfnr,
'datum' => $datum,
'zeit' => $zeit,
'thema' => $thema,
);
$this->insert($data);
}
I´m using a mySQL database on a WAMP installation.
Where is my error? As a remark I want to say, I get a new record, the value of "thema" and the keys are properly saved, so I think it must be some format thing somewhere.
EDIT: I get a new record but the fields date and time are empty. I get no errors
NEW: I added a debug test in my controller to see what comes for the date value, here is the answer:
string '01-04-2016' (length=10)
(I put in 01-04-2016)
By reading your comments I understand you have two problems. The first one is putting the date into your table and the second is to let the user use the normal date format (dd/mm/yyyy).
First problem is solved when you reformat the user input before putting it into the database.You can add the following line into the $form->isValid($formData) part:
$dat = (new DateTime($form->getValue('datum')))->format('Y-m-d');
This oneliner will convert the date from 'dd-mm-yyyy' to 'yyyy-mm-dd'.
thanks, after the suggestion to debug I changed the format of my date like this: $test1=date('Y/m/d',strtotime($dat));
And now it works!

Laravel form input integer length

In Laravel form input validation, you can specify a minimum and a maximum length of a given input field.
$inputRules = [
'postCode' => 'min:3|max:8'
];
Validation outcome
'BA45TZ' = true
'FF' = false
'GH22 55XYZ' = false
However if I do the same for a number, it will validate whether the input is less than or greater than the input, then return on that.
$inputRules = [
'cv2' => 'min:3|max:4'
];
Validation outcome
'586' = false
'4' = true
'2' = false
'3' = true
I actually want to validate a numbers length not it's numerical value. I can't figure out how to do this. Google has been no help, or I am not searching the right thing.
Anybody had any experience with this?
EDIT: I have answered my own question. I had missed Laravels digits_between.
Like an idiot, I missed Laravels digits_between validator rule. I swear I had scoured those rules, but here we are.
Thank you everyone for your help.
$inputRules = [
'cv2' => 'required|numeric|digits_between:3,4'
];
That's the expected behavior of Laravel's size, min and max validations. You can't change it.
For string data, value corresponds to the number of characters. For numeric data, value corresponds to a given integer value. For files, size corresponds to the file size in kilobytes.
To solve this you have to create a custom validation rule.
Something like this:
Validator::extend('min_length', function($attribute, $value, $parameters){
return strlen($value) >= $parameters[0];
});
Validator::extend('max_length', function($attribute, $value, $parameters){
return strlen($value) <= $parameters[0];
});
And you can use them in the same way:
'cv2' => 'min_length:3|max_length:4'
For length in number you've to use size, but you can't put ranges in it. So, the best thing to do is making a custom validation.
Here is the documentation in laravel: http://laravel.com/docs/5.0/validation#custom-validation-rules
And an example:
Validator::extend('minsize', function($attribute, $value, $parameters)
{
return strlen($value) >= $parameters[0];
});
And do the same with maxsize.

ZF2 validating date and time format PT_BR always The input does not appear to be a valid date

Project utilizing ZF2 + Doctrine 2.
I Tried many formats. I'm working with a Form without validation.
My last try was:
$traindate = new Element\DateTime('trainDate');
$traindate->setAttributes(array(
'name' => 'trainDate',
'id' => 'trainDate',
'size' => '30',
'class' => 'datepicker',
'options' => array(
'label' => '',
'format' => 'd-m-Y H:i'
),
));
I need to use a input to set a date and time of a event. On Brazil the basic format is:
14-05-2014 14:20
15-05-2015 15:00
With means Days Months Year Hour Minutes, like I'm expressing on the Options -> Format.
This way always when I try to insert, i get the following messsage:
The input does not appear to be a valid date
Removing the format, i can only pass by $form->isValid($data) by Y-m-d (American Format), but by the way i can't pass time to date too, which is causing me big troubles.
I need to set date PT_BR on Form/Input, Pass by validation, Convert Data do Mysql Format (YYYY-mm-dd HH:ii:ss).
And then retrive from db and convert back to pt_br format.
But not even i can pass time with date to zf2 form, ever this error message.
I remove all filters from this form trying to get work, but doesn't work.
Where is the main problem?
After a long time paying my attention to this problem I found the right and quick solution.
After 6 month making science, I got:
Right all:
$traindate = new Element\DateTime('trainDate');
$traindate->setAttributes(array(
'name' => 'trainDate',
'id' => 'trainDate',
'size' => '30',
'class' => 'datepicker',
));
$traindate->setFormat('d/m/Y'); //ONLY WORKS ON THIS FORMAT.
Docs and people over internet don't make it clear, but to set Format only works on this form.
And to grab this to Entity, you need to write your own Hydrator extending the DoctrineHydrator:
namespace Application\Hydrator;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
class MyCustomHydrator extends DoctrineObject {
protected function handleTypeConversions($value, $typeOfField)
{
if($typeOfField == 'datetime'){
return \DateTime::createFromFormat('d/m/Y', $value);
}
return parent::handleTypeConversions($value, $typeOfField);
}
}
It's make it simple to work with any date format. You can extend further making Locale assertions on this Custom Hydrator as you want.
I recommend you to do the date conversion work in your Train entity. The trainData's property getter and setter could be:
//THE PROPERTY IS IN MYSQL FORMAT, BUT THE GETTER WILL RETURN IT ALWAYS IN THE BRAZILIAN ONE
public function getTrainDateTime() {
return $this->trainDateTime->format( 'd/m/Y H:i' );
}
//IT WILL ALWAYS RECIEVE A BRAZILIAN DATETIME, CONVERT IT TO MYSQL FORMAT
public function setTrainDateTime( $trainDateTime ) {
$time = \DateTime::createFromFormat( 'd/m/Y H:i', $trainDateTime )->getTimestamp();
$this->trainDateTime = new \DateTime( date( 'Y-m-d', $time ) );
return $this;
}
If you do it this way, you can always work freely with brazilian dates, without worring about formats. The dirty work will be done by the entity class.

Laravel change input value

In laravel, we can get the input value via Input::get('inputname'). I try to change the value by doing this Input::get('inputname') = "new value";. But then, I get the error message saying Can't use function return value in write context.
Is it possible for us change the input value so that when later calling on Input::get('inputname') will get the new amended value?
Thanks.
You can use Input::merge() to replace single items.
Input::merge(['inputname' => 'new value']);
Or use Input::replace() to replace the entire input array.
Input::replace(['inputname' => 'new value']);
Here's a link to the documentation
If you're looking to do this in Laravel 5, you can use the merge() method from the Request class:
class SomeController extends Controller
{
public function someAction( Request $request ) {
// Split a bunch of email addresses
// submitted from a textarea form input
// into an array, and replace the input email
// with this array, instead of the original string.
if ( !empty( $request->input( 'emails' ) ) ) {
$emails = $request->input( 'emails' );
$emails = preg_replace( '/\s+/m', ',', $emails );
$emails = explode( ',', $emails );
// THIS IS KEY!
// Replacing the old input string with
// with an array of emails.
$request->merge( array( 'emails' => $emails ) );
}
// Some default validation rules.
$rules = array();
// Create validator object.
$validator = Validator::make( $request->all(), $rules );
// Validation rules for each email in the array.
$validator->each( 'emails', ['required', 'email', 'min: 6', 'max: 254'] );
if ( $validator->fails() ) {
return back()->withErrors($validator)->withInput();
} else {
// Input validated successfully, proceed further.
}
}
}
If you mean you want to overwrite input data, you can try doing:
Input::merge(array('somedata' => 'SomeNewData'));
Try this,it will help you.
$request->merge(array('someIndex' => "yourValueHere"));
I also found this problem, I can solve it with the following code:
public function(Request $request)
{
$request['inputname'] = 'newValue';
}
Regards
I'm using Laravel 8.
The following is working for me:
$request->attributes->set('name', 'Value');
I used Raham's answer to solve my problem. However, it was nesting the updated data within an array, when I needed it at the same level as other data. I used:
$request->merge('someIndex' => "yourValueHere");
A note other Laravel newbies, I used the merge method to account for an empty checkbox value in a Laravel 7 update form. A deselected checkbox on an update form doesn't return 0, it doesn't set any value in the update request. As a result that value is unchanged in the database. You have to check for a set value and merge a new value if nothing exists. Hope that helps someone.
Just a quick update. If the user doesn't check a box and I need to enter a value in the DB I do something like this in my controller:
if(empty($request->input('checkbox_value'))) {
$request->merge(['checkbox_value' => 0]);
}

Categories