Laravel 4 Validation is Broken - php

A simple date format mm/dd/yyyy validation is all I need...
$rules = array(
'renewal_date' => array('required', 'date_format:?')
);
What do I set the date format to? The Laravel documentation could be so much better.

Documentation is pretty clear to me, you should use
date_format:format
"The field under validation must match the format defined according to the date_parse_from_format PHP function."
Looking at it: http://php.net/manual/en/function.date-parse-from-format.php, I see you can do something like this:
$rules = array(
'renewal_date' => array('required', 'date_format:"m/d/Y"')
);
This is pure PHP test for it:
print_r(date_parse_from_format("m/d/Y", "04/01/2013"));
You can also do it manually in Laravel to test:
$v = Validator::make(['date' => '09/26/13'], ['date' => 'date_format:"m/d/Y"']);
var_dump( $v->passes() );
To me it's printing
boolean true

I got a similar problem, but with a d/m/Y date format.
In my case, the problem was that I defined both "date" and "date_format" rules for the same field:
public static $rules = array(
'birthday' => 'required|date|date_format:"d/m/Y"',
...
The solution is to remove the "date" validator: you must not use both. Like this:
public static $rules = array(
'birthday' => 'required|date_format:"d/m/Y"',
...
after that, all is well.

Workaround:
'renewal_date' => array('required', 'date_format:m/d/Y', 'regex:/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/')

You should use with double quote like "Y-m-d H:i:s"
$rules = array(
'renewal_date' => array('required', 'date_format:"m/d/Y"')
^ ^ this ones
);
Discussion about this issue on GitHub: https://github.com/laravel/laravel/pull/1192

date_format didn't work for me , so I did this custom validation
Validator::extend('customdate', function($attribute, $value, $parameters) {
$parsed_date = date_parse_from_format ( "Y-m-d" , $value);
$year = $parsed_date['year'];
$month = $parsed_date['month'];
$month = $month <= 9 ? "0" . $month : $month;
$day = $parsed_date['day'];
$day = $day <= 9 ? "0" . $day : $day;
return checkdate($month, $day, $year);
});
$validation = Validator::make(
array('date' => $num),
array('date' => 'customdate')
);

Use the PHP date_parse_from_format (Laravel 4):
'birthday' => 'date_format:m/d/Y'
Your validation message will also use "m/d/Y" which the average user will not understand.
The birthday does not match the format m/d/Y
Recommend customizing your message for this invalid response.
The birthday does not match the format mm/dd/yyyy

Source : Click Here
You can use like
$rules = [
'start_date' => 'date_format:d/m/Y|after:tomorrow',
'end_date' => 'date_format:d/m/Y|after:start_date',
];

Related

updateOrCreate does not match Carbon date

I am using Laravel Framework 6.16.0 and I am creating from a string a date object so that I can input it in my db:
$transaction_date = Carbon::createFromFormat('Y-m-d', $tradeDate);
$filling_Date = Carbon::createFromFormat('Y-m-d H:i:s', $fillingDate, 'UTC');
$product = Product::updateOrCreate(
[
'price' => trim($price),
'qty' => $qty,
'companies_id' => $company->id,
'persons_id' => $person->id,
'amount_range' => $owned,
'filling_date' => $filling_Date,
'transaction_date' => $transaction_date,
],
[]
);
When running the above query my product does not get found as $filling_Date and $transaction_date are not matched in the database, even if my product already exists.
I am guessing, the reason is that I am creating a "new" Carbon object.
Any suggestions how to match the filling_date and transaction_date in the database?
I appreciate your replies!
Try this when converting a string to a date with Carbon
$date = Carbon::parse($yourStringDate);

CakePHP 3: Error while passing an array in URL

I am trying to pass datetime variables into my exportcsv method to generate .csv file with data from indicated time period.
Both variables are associative arrays that look like this:
[
'beginning' => [
'year' => '2016',
'month' => '06',
'day' => '23',
'hour' => '11',
'minute' => '15'
],
'end' => [
'year' => '2016',
'month' => '06',
'day' => '29',
'hour' => '11',
'minute' => '15'
]
]
When I try to pass variables I get an error with this message (yep, I've got the same two warnings):
Warning (2): rawurlencode() expects parameter 1 to be string, array given [CORE\src\Routing\Route\Route.php, line 574]
Warning (2): rawurlencode() expects parameter 1 to be string, array given [CORE\src\Routing\Route\Route.php, line 574]
rawurlencode() is a basic PHP function and this is the line 574:
$pass = implode('/', array_map('rawurlencode', $pass));
It looks like some problem with URL rewriting, but frankly I don't know how to fix it. Any ideas?
exportcsv method in EventsController
public function exportcsv($beginning = null, $end = null)
{
if ($this->request->is('post')) {
$beginning = $this->request->data['Export']['beginning'];
$end = $this->request->data['Export']['end'];
return $this->redirect([$beginning, $end]);
}
if (!$beginning && !$end) {
return $this->render();
}
$this->response->download('export.csv');
$data = $this->Events->find('all')
->select([
'title',
'created',
'description',
'ended',
'working_hours',
'price',
'username' => 'Users.name',
'statusname' => 'Statuses.name',
'employeename' => 'Employees.name'
])
->leftJoinWith('Statuses')
->leftJoinWith('Users')
->leftJoinWith('Employees')
->where(["created BETWEEN " . $beginning . " AND " . $end])
->autoFields(true)
->toArray();
$_serialize = 'data';
$_delimiter = chr(9); //tab
$_extract = ['title', 'created', 'description', 'ended', 'working_hours', 'price', 'username', 'statusname', 'employeename'];
$this->set(compact('data', '_serialize','_delimiter', '_extract'));
$this->viewBuilder()->className('CsvView.Csv');
return;
}
exportcsv.ctp view:
<div class="events form large-6 medium-4 columns content">
<?= $this->Form->create('Export'); ?>
<?= $this->Form->input('beginning', array('type'=>'datetime', 'interval' => 15, 'label' => 'Beginning:')); ?>
<?= $this->Form->input('end', array('type'=>'datetime', 'interval' => 15, 'label' => 'End:')); ?>
<?= $this->Form->button(__('Add')) ?>
<?= $this->Form->end() ?>
</div>
You cannot pass arrays in a URL array, the router doesn't support that. Also you need to additionally pass Instead, convert your single values to proper datetime strings, you could easily do that via the DateTimeType class, something like
if ($this->request->is('post')) {
$beginning = $this->request->data('Export.beginning');
$end = $this->request->data('Export.end');
$type = \Cake\Database\Type::build('datetime');
$beginning = $type->marshal($beginning)->format('Y-m-d H:i:s');
$end = $type->marshal($end)->format('Y-m-d H:i:s');
return $this->redirect([
$beginning,
$end
]);
}
Also, as already mentioned in the comments, you need to fix your where() call, as currently it has an SQL injection vulnerability. The keys of key => value items, as well as value only items, are not going to be bound, but inserted into the query directly!
Cakes expression builder ships with methods to safely generate BETWEEN expressions:
->where(function(\Cake\Database\Expression\QueryExpression $exp) use ($beginning, $end) {
return $exp->between('Events.created', $beginning, $end);
});
See also
API > \Cake\Database\DateTimeType::marshal()
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions
CakePHP 3.0 -> Between find condition
your redirect is wrong
return $this->redirect([
'controller' => 'yourController',
'action' => 'yourAction',
$yourData]
);
see the Cookbook for more information on this topic

Select a SubArray if today date is between 2 keys value

I have a multidimensional array like this:
$array = array(
0 => array(
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
),
1 => array(
'name' => 'second element',
'start' => '01/07/2015',
'end' => '30/09/2015'
),
2 => array(
'name' => 'fourth element',
'start' => '01/10/2015',
'end' => '15/12/2015'
)
);
I need to select one array subarray (item) based on the today date.
today date must be between start date and end date keys.
In the end I would like to have this:
$selected_subarray = array (
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
)
I use to check between two dates like this:
function check_if_in_range($start_date, $end_date, $today_date)
{
$start_d = strtotime($start_date);
$end_d = strtotime($end_date);
$today_d = strtotime($today_date);
return (($today_d >= $start_d) && ($today_d <= $end_d));
}
I tryed to follow suggestions from this question How to search by key=>value in a multidimensional array in PHP
but if I'm able to filter for a key = value, I'm not able to do the same using the "check_if_in_range" function.
You do know that 30/06/2015 is invalid date, and strtotime() will return false? See here. Format mm/dd/yyyy is an American month, day and year. So your format is non-standard.
Best way is to convert it to standard format, and then use strtotime()example or just use DateTime::createFromFormat()example.
After you learn how formating and converting dates works, then you can just do simple foreach loop, and break on first found result. Here is a little demo.
Try something like the following
foreach($array as $key => $value) {
if(check_in_range($value['start'], $value['end'], $today_date)) {
$selected_subarray = $value;
}
}

Retrieve data based on year and month in cakephp

I am trying to create a get statements function and I have some problems defining the date range.
The data will be passed via get method in the following format: ?year=yyyy&month=mm
The relevant column of the table has datetime type (2012-02-01).
I checked the TimeHelper class and more particularly the TimeHelper::daysAsSql($begin, $end, $fieldName, $timezone = NULL) but i am not sure if it applies for this case.
I was thinking if i can create a date in the format of Y-m using the two variables year and month and then use it in the conditions for retrieving the data but I am sure there is a more efficient and proper way. Could anyone help?
$user_id = $Client['Client']['id'];
$year = $this->request['url']['year'];
$month = $this->request['url']['month'];
//$date_created = date('Y-m');
if (!empty($user_id) && (!empty($date_created))) {
$Reports = $this->Report->find('all', array(
'fields' => array('amount','currency','date_created','invoice_no'),
'conditions' => array(
'Report.client_id'=> $user_id,
'Report.date_created >=' => $date_created,
'Report.date_created <=' => $date_created
),
)
);
MONTH(dateColumn) Returns an integer that represents the month of the specified date.
YEAR(dateColumn) Returns an integer that represents the year of the specified date.
InCakephp use as
$user_id = $Client['Client']['id'];
$year = $this->request['url']['year'];
$month = $this->request['url']['month'];
//$date_created = date('Y-m');
if (!empty($user_id) && (!empty($date_created))) {
$Reports = $this->Report->find('all', array(
'fields' => array('amount','currency','date_created','invoice_no'),
'conditions' => array(
'Report.client_id '=> $user_id,
'MONTH(date_created ) >='=> $month,
'YEAR(date_created ) <=' => $year
),
)
);

MySQL query for dates with CakePHP

I'm trying to select the values that fall between 2 dates, so I'll have to use <= and >=, however, my query is seemingly behaving as just less than or greater than and not considering values equal to the date.
I'm using CakePHP which saves dates in "Y-m-d h:i:a" format. I wanted to find dates on given week intervals (starting on Sundays), so I used the following.
$start_date = date('Y/m/d', strtotime('last Sunday', strtotime($timestamp)));
$formatted_start_date = str_replace("/","-",$start_date);
I tried to do find $start_date formatted as "Y-m-d" but then it wouldn't find the correct date, so I switched it to the way it is and used str_replace to format it to using "-" instead of "/".
$date_query = $this->Order->query("select * from orders where id = '$id' and created => '$formatted_start_date' and created <= '$current_timestamp' ");
Considering the time values in my database are in "Y-m-d h:i:a" format, can I use "Y-m-d" for date comparison? Is it possible to do a MySQL query that involves both LIKE and <= ?
No need to do a str_replace() - just get the Y-m-d:
$start_date = date('Y-m-d', strtotime('last Sunday', strtotime($timestamp)));
Then, instead of manually creating a query, use the CakePHP conventions (yes, you can use Y-m-d for date comparison even though the datetimes stored in the database are Y-m-d H:i:s)
$this->Order->find('all', array(
'conditions' => array(
'id' => $id,
'created >=' => $start_date,
'created <=' => $end_date . ' 23:59:59',
'my_field LIKE' => '%whatever%'
));
Though - this seems kind of strange - usually you're either looking for something by 'id' OR by a date range - not both. But - maybe you have a reason :)
And as you can see above, yes, you can add a 'LIKE' also if you need.
Above answer is totally correct, but you can take easier approach using cakePHP time helper, which has function daysAsSql, it transcribes and time-readable strings into database range.
http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::daysAsSql
Just add condition's array like this.
$resl = $this->DBNAME->find('all',array(conditions=>array('date1>date','date1<date')));
Replace 'date' with your date.
This is worked for me.
Try this in your controller
$searchTutorQuery = $this->Tutordetails->find('all', array(
'conditions' => array(
"User.zip" => $zipcode1,
"Tutordetails.user_id"=>$uid,
"Tutordetails.subject_id" => $subjectName,
"Tutordetails.hourly_rate >=" => $hourly_rate
),
//"User.id =" => $userid,
'fields' => array('user_id', 'Tutordetails.subject_id', 'Tutordetails.hourly_rate',
'User.zip', 'Tutordetails.zip'),
'order' => array('Tutordetails.id DESC')
));

Categories