How to format date fields before save in CakePHP 3? - php

I used this in AppController:
Time::setToStringFormat('dd/MM/YYYY');
The date field in my form is a input type "text" to allow my user writes something like 31/12/2015.
However when I try to save (MySQL date) I get some errors of Time Class because inside the table the value now is 00-00-0000
Alunos Controller code
Thanks !

My final solution was this on bootstrap:
date_default_timezone_set('America/Sao_Paulo');
setlocale(LC_ALL, 'pt_BR', 'pt_BR.utf-8', 'pt_BR.utf-8', 'portuguese');
Type::build('time')->useImmutable();
Type::build('date')->useImmutable()->useLocaleParser();
Type::build('datetime')->useImmutable()->useLocaleParser();
Type::build('timestamp')->useImmutable();
\Cake\I18n\Time::setToStringFormat('dd/MM/yyyy HH:mm:ss');
\Cake\I18n\Date::setToStringFormat('dd/MM/yyyy');
\Cake\I18n\FrozenTime::setToStringFormat('dd/MM/yyyy HH:mm:ss');
\Cake\I18n\FrozenDate::setToStringFormat('dd/MM/yyyy');
\Cake\I18n\I18n::locale('pt-BR'); //new !
Type::build('decimal')->useLocaleParser();
Type::build('float')->useLocaleParser();

maybe this could help someone.
public function beforeSave($event, $entity, $options) {
$entity->dateField = date('Y-m-d', strtotime($entity->dateField));
}

If you are just creating a new application with a fresh database, delete does dates having 0000-00-00 and change the column definition so it can accept nulls. Using 0000-00-00 for dates is usually a really bad thing as only errors and bugs can come out of it :)
Edit based on the comments below
It seems like the problem was getting a string field to be parsed from the local date format to what php can understand. For this task you just need to configure the DateTimeType class to parse the dates using a locale-aware format as described here http://book.cakephp.org/3.0/en/orm/database-basics.html#parsing-localized-datetime-data
// In bootstrap.php or AppController or your controller action:
use Cake\Database\Type;
...
Type::build('datetime')->useLocaleParser();
You can also set the locale parser to parse a specific format. For the code above to work, make sure you set your application to use a locale:
I18n::locale('fr-FR')

Easy solution insert date format in CakePHP 3.x in Models and custom out views:
Insert ['rule' => ['date','dmy']]
Example
public function validationDefault(Validator $validator)
{
...
$validator
->add('demo_example_date', 'valid', ['rule' => ['date','dmy']]) //Format valid '30-12-2015' or '30-12-05'
->requirePresence('demo_example_date', 'create')
->notEmpty('factura_fecha');
...
return $validator;
}
Out view, set AppController
...
use Cake\I18n\Time;
use Cake\Database\Type;
Time::$defaultLocale = 'es-ES';
Time::setToStringFormat('dd-MM-YYYY');
Type::build('datetime')->useLocaleParser();
class AppController extends Controller
{
...
}

works for me using Postgres.
File config/app.php
in variable Datasources['default'] add command 'SET datestyle TO ISO, DMY' to init
'Datasources' => [
'default' => [
'init' => ['SET datestyle TO ISO, DMY '],
],
in mysql
https://my.vertica.com/docs/7.1.x/HTML/Content/Authoring/SQLReferenceManual/Statements/SET/SETDATESTYLE.htm

Related

Symfony: How to use Data Transformers with a FormFactory?

In my Symfony Application i have a From which contains a lot of checkboxes, radios, textfields and also DateTime Objects.
Everything but the DateTime Objects work fine, but with them i always get the error "Object of class DateTime could not be converted to string"
So i wanted to use this tutorial to change the datetime object to a string.
The thing is i am using a FormFactory and when i use the addModelTransformer()-Method like this...
1st Option:
$form->add($formFactory->createNamed('value', 'date', null, $fieldOptions));
$form->get('value')->addModelTransformer(new CallbackTransformer(
function($dateAsDate){
return $dateAsDate->format('Y-m-d');
},
function ($dateAsString){
return "test"; //TODO: to be changed to make string to date
}
));
...i get the Error "Call to undefined method Symfony\Component\Form\Form::addModelTransformer() "
When i use the builder function outside the Formfactory like this...
2nd Option:
//$builder->addEventListener Stuff is above
$builder->get('value')->addModelTransformer(new CallbackTransformer(
function($dateAsDate){ return $dateAsDate->format('Y-m-d'); },
function ($dateAsString){ return 'null'; } //TODO: to be changed to make string to date
));
...i get the Error "The child with the name "value" does not exist."
Does anybody have an idea how to make this work?
There is no need to use any custom Tranformer here.
The DateType field handles DateTime objects correctly by itself.
You may want to specify some options like 'format' and 'widget' depending on how you want to render your field, but the default 'input' should work fine with DateTime.
For example :
$builder->add('value', DateType::class, [
'format' => 'y-MM-dd',
'widget' => 'single_text', // To have a single input text box
'input' => 'datetime' // This is the default value
];

DateTime not save properly in cakephp 3.x with bootstrap datetimepicker

i am using cakephp 3.x, i have one form in which one field is of date. in backend i am using mysql.
my field structure in mysql is dob of type date.
now in cakephp 3.x i had use below syntax to create input.
echo $this->Form->input('dob', array(
'label' => (__('Date of Birth')),
'type' => 'text',
'required' => false,
'class' => 'form-control date'
));
and i had used bootstrap datetimepicker like,
$('.date').datetimepicker({
format: 'YYYY-MM-DD'
});
now when i submit the form at and i print_r the request data at that time i got this field like this
[
....
'dob' => '2016-02-11',
....
]
but when i save the record and look in database then it show me random date like 2036-10-25
can anyone help me please?
and this is the Final General Solution,
//File : src/Model/Table/PatientsTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Event\Event;
use ArrayObject;
use Cake\I18n\Time;
class PatientsTable extends Table
{
...
...
public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
if (isset($data['dob'])) {
$data['dob'] = Time::parseDate($data['dob'], 'Y-M-d');
}
}
}
You declared dob type as date but tried to save date in string format instead of date time format. Try this
use Cake\I18n\Time;
$this->request->data['dob']= Time::parseDate($this->request->data['dob'],'Y-M-d');

CakePHP 3 - FriendsOfCake Search Plugin - Convert date format before data is compared

Plugin: FriendsOfCake/Search
CakePHP Version: 1.3.4
I use the search plugin to filter data with a form in a view. In the database, fields of type DATE have the format YYYY-mm-dd but in the input field on the page the data needs to be inserted like dd.mm.YYYY by the user.
So I need to convert the date inserted in the form field to the format used in the database before values are compared.
What I don't get is where to actually "grab" the value to do the convertion within the plugins setup. I tried some things in the controller to either convert "return_ticket" or "opening_date" before they are compared with each other but I can't figure out anything that's working. Can someone help me with this?
At which point could I do the date/string convertion in the following setup?
// plugin settings in table
class TicketsTable extends Table
{
public function searchConfiguration()
{
$search = new Manager($this);
$search->value('ticket_return',[
'field' => $this->Appointments->target()->aliasField('opening_date')
]);
return $search;
}
// search setup in controller
class TicketsController extends AppController
{
public function index()
{
$query = $this->Tickets
->find('search',
$this->Tickets->filterParams($this->request->query))
}
}
// search form in view
<?= $this->Form->input(
'ticket_return', [
'label' => 'search date'
'default' => $this_date // today
])
?>

CakePHP: Validate date as 'dmy' but save to MySQL as correct date

I have a CakePHP 2.7 app. In my model I have the following validation:
public $validate = [
'trip_start' => [
'rule' => ['date', 'dmy'],
'message' => 'Date format is DD/MM/AAAA'
];
This work fine for client side validation and I can validate the user is selecting the date correctly.
But for saving to MySQL, the format expected is YYYY-mm-dd. What's the "standard" solution for this? Modify the beforeSave? The problem is that there needs to be 2 different validations. One in the format I expect the user to enter a date (even with a datepicker) and another in the format MySQL expects.
The CakeTime class is made for it.
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2015-07-24', '%d-%m-%Y');
return 24-07-2015
in your case you just have to reformat your data after the validation:
public function afterValidate(){
$this->request->data['Model']['fieldName'] = CakeTime::format($this->request->data['Model']['fieldName'], '%Y-%m-%d');
}

How can i add the current time in datetime format to a textfield in yii?

Here's the code i want to work with
<?php echo $form->textField($model,'email_time_created',array('readonly'=>true)); ?>
i want to automatically add the current time to my database
I recommend it to add it at the database, asuming you're using MySQL you can create a trigger before saving and doing something like this:
SET NEW.email_time_created=NOW()
If not, you can do it at Yii/PHP level by adding the following function at the model class:
public function beforeSave(){
$this->email_time_created = CDbExpression('NOW()'); //Only in MYSQL
return parent::beforeSave();
}
It will set the column to the current value before saving the model. Notice that it won't be shown at the form, but you can add it by JS or using php's date() at the form's view.
also you can set the value in controller.
$model->email_time_created= now('Y-m-d H:i:s');
The simplest way is to add CTimestampBehavior to your model:
public function behaviors(){
return array(
'CTimestampBehavior' => array(
'class' => 'zii.behaviors.CTimestampBehavior',
'createAttribute' => 'create_time_attribute',
'updateAttribute' => 'update_time_attribute',
)
);
}
See API.

Categories